Создание класса

dz4jke
Offline
Зарегистрирован: 01.06.2018

Добрый день товарищи, может кто подскажет мне решение моей проблемы, ну или хотя бы наведет на путь истинный) 

в общем появилась задача получить давление с датчика, использую внешний АЦП, захотел разделить все свое мракобесие по классам, что бы порядок в коде был более или менее, ну и к тому же проще создавать объекты датчиков( у каждого свои поля, и методы), но в итоге наткнулся на грабли с этим самым внешним АЦП. надо его инициализировать в основном файле скетча, а если мне нужно его методы заиспользовать в классе который я создаю, как быть то тогда? Надеюсь объяснил более менее доступно, я начинающий, поэтому некоторые моменты мне тяжело даются, но я стараюсь) 

Код класса который я хочу написать

#pragma once
#include <Arduino.h>
#include <Adafruit_ADS1X15.h>

class PressureSensor
{
public:
    PressureSensor(Adafruit_ADS1115 ads, uint8_t sensorPin, int16_t sensorMaxRange);
    float getPressureInPsi();
    float getPressureInBar();
private:
      uint8_t _sensorPin;    
    int16_t _sensorMaxRange; // PSI
    uint16_t _sensorAtmosphereADC;
    Adafruit_ADS1115 &_ads;

    void colibrationSensors();
    uint16_t getADCPressure();
};

PressureSensor::PressureSensor(Adafruit_ADS1115 ads, uint8_t sensorPin, int16_t sensorMaxRangeInPSI)
{
    _sensorPin = sensorPin;
    _sensorMaxRange = sensorMaxRangeInPSI;
    _ads = ads;
    colibrationSensors();
}

uint16_t PressureSensor::getADCPressure()
{
    uint8_t numSamples = 10;               // количество образцов для массива
    uint16_t arrSensorSamples[numSamples]; // создаем массив хранения значений АЦП
    uint16_t ResultADC = 0;                // переменная значений АЦП датчика низкого давления
    /*заполяем массив данных АЦП*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик заполнения массива АЦП
    {
        arrSensorSamples[i] = _ads.readADC_SingleEnded(_sensorPin); //считывание данных АЦП
    }
    /*находим среднее значение в массиве*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик суммирования значений массива АЦП
    {
        ResultADC += arrSensorSamples[i]; // суммирование значений массива
    }
    ResultADC /= numSamples; // выводим среднее значение массива АЦП датчика низкого давления
    return ResultADC;
}

void PressureSensor::colibrationSensors()
{
    _sensorAtmosphereADC = getADCPressure();
}

float PressureSensor::getPressureInPsi()
{
    float pressure = (float)((int16_t)(getADCPressure() - _sensorAtmosphereADC)) * _sensorMaxRange / (24000 - _sensorAtmosphereADC); // 24000 ADC == 4,5V max range of sensor
    return pressure;
}

float PressureSensor::getPressureInBar()
{
    return 0.06895 * getPressureInPsi();
}

 Основной класс программы

#include <Arduino.h>
#include <PressureSensor.h>
//#include <Adafruit_ADS1X15.h> // Библиотека для работы с модулями ADS1115 и ADS1015
Adafruit_ADS1115 ads; // Создание объекта ads

PressureSensor hpSensor(ads0500);
PressureSensor lpSensor(ads1185);

void setup()
{
  ads.setGain(GAIN_TWOTHIRDS);
  ads.begin();
  Serial.begin(9600);
}

void loop()
{

  Serial.println(hpSensor.getPressureInBar());
  delay(1000);
}

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

А почему нельзя а) инициализировать объект ads в классе (у вас вроде так и есть)? б) передать объект в класс по указателю?

dz4jke
Offline
Зарегистрирован: 01.06.2018

этот код, который я предоставил, не работает, точнее он компилируется, заливается, но ничего не происходит.

 

rkit
Offline
Зарегистрирован: 23.11.2016

dz4jke пишет:

 а если мне нужно его методы заиспользовать в классе который я создаю, как быть то тогда?

Тогда используй методы в классе.

dz4jke
Offline
Зарегистрирован: 01.06.2018

Я дико извиняюсь, но я слегка не понимаю о чем вы сейчас, могли бы хотя бы как то намекнуть это написав кусочек того, о чем думаете в виде кода) 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

dz4jke пишет:

этот код, который я предоставил, не работает, точнее он компилируется, заливается, но ничего не происходит.

Этот и не должен работать. Начиная с конструктора

dz4jke
Offline
Зарегистрирован: 01.06.2018

б) передать объект в класс по указателю

я хотел попробовать что то подобное, я просто изучаю Java, и побочно пытаюсь воевать с ардуино, в Java с этим как то попроще, в С++ и указатели и ссылки... хз что ) ну в общем постараюсь сейчас что-нибудь вычитать в инете, мало ли получится, спасибо за совет

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019
DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
uint16_t PressureSensor::getADCPressure()
{
    const uint8_t NUM_SAMPLES = 16;               // количество образцов для массива
    uint16_t ResultADC = 0;                // переменная значений АЦП датчика низкого давления
    /*заполяем массив данных АЦП*/
    for (uint8_t i = 0; i < NUM_SAMPLES; i++) //счетчик заполнения массива АЦП
    {
        ResultADC +=  _ads.readADC_SingleEnded(_sensorPin); //считывание данных АЦП
    }
     ResultADC >>= 4; // выводим среднее значение массива АЦП датчика низкого давления
    return ResultADC;
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А что код основной программы нормально вставить не судьба? Вставлялка поломалась? Или таки вставите? Сделайте уж милость! А то ни к себе скопировать, ни на номер строки сослаться.

dz4jke пишет:
Надеюсь объяснил более менее доступно
Зря надеетесь. Я вот лично НИХРЕНА не понял. Я не понял главного - в чём именно у  Вас проблема?

На то, что Вы пишете я могу ответить так

dz4jke пишет:
грабли с этим самым внешним АЦП. надо его инициализировать в основном файле скетча, а если мне нужно его методы заиспользовать в классе который я создаю, как быть то тогда?
Ну, так и быть! Используйте. Кто или что мешает?

Но Вы же не этого ждёте.

Вставьте правильно код и попытайтесь внятно сформулировать свою проблему.

dz4jke
Offline
Зарегистрирован: 01.06.2018
#include <Arduino.h>
#include <PressureSensor.h>
//#include <Adafruit_ADS1X15.h> // Библиотека для работы с модулями ADS1115 и ADS1015
Adafruit_ADS1115 ads; // Создание объекта ads

PressureSensor hpSensor(ads, 0, 500);
PressureSensor lpSensor(ads, 1, 185);

void setup()
{
  ads.setGain(GAIN_TWOTHIRDS);
  ads.begin();
  Serial.begin(9600);
}

void loop()
{

  Serial.println(hpSensor.getPressureInBar());
  delay(1000);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

И проблему объясните, а то я реально не понимаю в чём она.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А! догадался. Вы в восьмой строке & пропустили между Adafruit_ADS1115 и ads

Как вставите, не забудьте и про 21-ую - они с восьмой в связке - должно быть одинаково.

dz4jke
Offline
Зарегистрирован: 01.06.2018

Извиняюсь за то что заставил Вас нервничать своим разгильдяйством)) код вроде исправил

в общем проблема такая, постараюсь объяснить как могу

у меня есть два датчика давления, 0.5...4.5 в, один -1...185 PSI, второй 0...500 PSI

для более точного измерения давления, приобрел внешний ацп ads1115, так как встроенного в ардуино не хватало.

скачал библиотеку  AdaFruit_ADS1x15.h и написал все в процедурном стиле, все работает, показания снимаются.

Задумался о том, чтобы написать что-то на подобии библиотеки для своих датчиков, где все необходимые для работы поля будут храниться внутри класса, ну а я в создав два объекта этого класса в основном файле программы(где функция setup(), и loop()) буду использовать только пару методов для получения давления в PSI и в Bar, выводить на дислей.

Так вот, столкнулся я с такой проблемой, что в методе 

uint16_t PressureSensor::getADCPressure()
{
    uint8_t numSamples = 10;               // количество образцов для массива
    uint16_t arrSensorSamples[numSamples]; // создаем массив хранения значений АЦП
    uint16_t ResultADC = 0;                // переменная значений АЦП датчика низкого давления
    /*заполяем массив данных АЦП*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик заполнения массива АЦП
    {
        arrSensorSamples[i] = _ads.readADC_SingleEnded(_sensorPin); //считывание данных АЦП
    }
    
    /*находим среднее значение в массиве*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик суммирования значений массива АЦП
    {
        ResultADC += arrSensorSamples[i]; // суммирование значений массива
    }
    ResultADC /= numSamples; // выводим среднее значение массива АЦП датчика низкого давления
    return ResultADC;
}

необходимо использовать метод объекта класса AdaFruit_ADS1x15,  он же _ads.readADC_SingleEnded(_sensorPin)

так вот, создав объект AdaFruit_ADS1115 _ads; внутри  своего класса Class PressureSensor не могу получать показания по понятным причинам, потому что внешний ацп имеет еще два метода для инициализации

ads.setGain(GAIN_TWOTHIRDS);
ads.begin();

вопрос заключается в следующем, как лучше поступить? создать объект внутри моего класса, так не прокатило, я даже создавал отдельный метод для инициализации

void PressureSensor::initialization()
{
    ads.setGain(GAIN_TWOTHIRDS);
    ads.begin();
}

и далее его вставлял в метод setup(); в основном классе, ничего не помогло. 

дали совет передать ссылку, но я пока немного не пойму как это правильно описать в коде, постараюсь вычитать, разобраться, если конечно получится.

Надеюсь сейчас объяснил более или менее, стараюсь как могу, я не программист, и заранее прошу прощения за некомпетентность

 

dz4jke
Offline
Зарегистрирован: 01.06.2018
 
#pragma once
#include <Arduino.h>
#include <Adafruit_ADS1X15.h>

class PressureSensor
{
public:
    PressureSensor(Adafruit_ADS1115 &ads, uint8_t sensorPin, int16_t sensorMaxRange);
    float getPressureInPsi();
    float getPressureInBar();

private:
    //все что отностися к датчикам давления
    uint8_t _sensorPin;      // вывод на который подключени датчик давления
    int16_t _sensorMaxRange; // PSI
    uint16_t _sensorAtmosphereADC;
    Adafruit_ADS1115 _ads;

    void colibrationSensors();
    uint16_t getADCPressure();
};

PressureSensor::PressureSensor(Adafruit_ADS1115 &ads, uint8_t sensorPin, int16_t sensorMaxRangeInPSI)

{
    _sensorPin = sensorPin;
    _sensorMaxRange = sensorMaxRangeInPSI;
    _ads = ads;
    colibrationSensors();
}

uint16_t PressureSensor::getADCPressure()
{
    uint8_t numSamples = 10;               // количество образцов для массива
    uint16_t arrSensorSamples[numSamples]; // создаем массив хранения значений АЦП
    uint16_t ResultADC = 0;                // переменная значений АЦП датчика низкого давления
    /*заполяем массив данных АЦП*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик заполнения массива АЦП
    {
        arrSensorSamples[i] = _ads.readADC_SingleEnded(_sensorPin); //считывание данных АЦП
    }

    /*находим среднее значение в массиве*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик суммирования значений массива АЦП
    {
        ResultADC += arrSensorSamples[i]; // суммирование значений массива
    }
    ResultADC /= numSamples; // выводим среднее значение массива АЦП датчика низкого давления
    return ResultADC;
}

void PressureSensor::colibrationSensors()
{
    _sensorAtmosphereADC = getADCPressure();
}

float PressureSensor::getPressureInPsi()
{
    float pressure = (float)((int16_t)(getADCPressure() - _sensorAtmosphereADC)) * _sensorMaxRange / (24000 - _sensorAtmosphereADC); // 24000 ADC == 4,5V max range of sensor
    return pressure;
}

float PressureSensor::getPressureInBar()
{
    return 0.06895 * getPressureInPsi();
}

так должно быть?

rkit
Offline
Зарегистрирован: 23.11.2016
    Adafruit_ADS1115 &_ads;

    void colibrationSensors();
    uint16_t getADCPressure();
};

PressureSensor::PressureSensor(Adafruit_ADS1115 &ads, uint8_t sensorPin, int16_t sensorMaxRangeInPSI): _ads(ads)

{
    _sensorPin = sensorPin;
    _sensorMaxRange = sensorMaxRangeInPSI;
    colibrationSensors();
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

dz4jke пишет:

так должно быть?

Простите, Вы программист и просто троллите нас?

Другим я не могу объяснить Вашего поведения.

В строке №15 кода из первого поста было правильно написано

Adafruit_ADS1115 &_ads;

а что написано в строке №17 этого кода? Я Вам подсказал куда нужно добавить амперсанд, Вы добавили а оттуда, где он был - убрали? Зачем? У Вас дефицит амперсандов? Или троллите?

Другое дело, что так оно не будет компилироваться, Вам нужно

ИЛИ инициализировать ссылку прямо в объявлении конструктора через двоеточие (как подсказал коллега чуть выше)

ИЛИ отказаться от ссылки и использовать указатель.

dz4jke
Offline
Зарегистрирован: 01.06.2018

Да не троллю я вас, уже пихал я амперсанты уже во все места)) и все равно ничего не работает)

#include <Arduino.h>
//#include <Adafruit_ADS1X15.h>
// Создание объекта ads

class PressureSensor
{
public:
    PressureSensor(Adafruit_ADS1115 &ads, uint8_t sensorPin, int16_t sensorMaxRange);
    float getPressureInPsi();
    float getPressureInBar();

private:
    //все что отностися к датчикам давления
    uint8_t _sensorPin;      // вывод на который подключени датчик давления
    int16_t _sensorMaxRange; // PSI
    uint16_t _sensorAtmosphereADC;
    Adafruit_ADS1115 &_ads;

    void colibrationSensors();
    uint16_t getADCPressure();
};

PressureSensor::PressureSensor(Adafruit_ADS1115 &ads, uint8_t sensorPin, int16_t sensorMaxRangeInPSI)
{
    _sensorPin = sensorPin;
    _sensorMaxRange = sensorMaxRangeInPSI;
    _ads = ads;
    colibrationSensors();
}

uint16_t PressureSensor::getADCPressure()
{
    uint8_t numSamples = 10;               // количество образцов для массива
    uint16_t arrSensorSamples[numSamples]; // создаем массив хранения значений АЦП
    uint16_t ResultADC = 0;                // переменная значений АЦП датчика низкого давления
    /*заполяем массив данных АЦП*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик заполнения массива АЦП
    {
        arrSensorSamples[i] = _ads.readADC_SingleEnded(_sensorPin); //считывание данных АЦП
    }

    /*находим среднее значение в массиве*/
    for (uint8_t i = 0; i < numSamples; i++) //счетчик суммирования значений массива АЦП
    {
        ResultADC += arrSensorSamples[i]; // суммирование значений массива
    }
    ResultADC /= numSamples; // выводим среднее значение массива АЦП датчика низкого давления
    return ResultADC;
}

void PressureSensor::colibrationSensors()
{
    _sensorAtmosphereADC = getADCPressure();
}

float PressureSensor::getPressureInPsi()
{
    float pressure = (float)((int16_t)(getADCPressure() - _sensorAtmosphereADC)) * _sensorMaxRange / (24000 - _sensorAtmosphereADC); // 24000 ADC == 4,5V max range of sensor
    return pressure;
}

float PressureSensor::getPressureInBar()
{
    return 0.06895 * getPressureInPsi();
}

 

 

 

#include <Arduino.h>
#include <Adafruit_ADS1X15.h>
#include <PressureSensor.h>

Adafruit_ADS1115 ads;

PressureSensor hpSensor(ads, 0, 500);
//PressureSensor lpSensor(ads, 1, 185);

void setup()
{
  Serial.begin(9600);
  ads.setGain(GAIN_TWOTHIRDS);
  ads.begin();
}

void loop()
{
  // Serial.println("hello");
  Serial.println(hpSensor.getPressureInBar());
  delay(500);
}

 ну вот по вашему я так понимаю должно получится, и ничего не работает, я уже и добавлял их и убирал, и что то не срастается.

и я же говорю, я не программист, изучаю Java, он похож на c++, но далеко не во всем, так что не ругайтесь. 

 

b707
Offline
Зарегистрирован: 26.05.2017

dz4jke пишет:

и я же говорю, я не программист, изучаю Java, он похож на c++, но далеко не во всем, так что не ругайтесь. 

вы этим заявлением что хотите вызвать, сочувствие?

Как можно относится к человеку, который пытается создавать классы С++, изучая Яву?  По-моему это просто издевательство над здраым смыслом.

Если уж полезли в улучшательство, переписывая работающий процедурный код на классы (зачем?) - то хотя бы почитайте книжки, как это делать правильно, а не суйте "амперсанды во все места"

 

dz4jke
Offline
Зарегистрирован: 01.06.2018

Всем спасибо, буду разбираться дальше

dz4jke
Offline
Зарегистрирован: 01.06.2018

За это исправление спасибо, попробовал, все работает, правда не совсем понял как)) 

b707
Offline
Зарегистрирован: 26.05.2017

dz4jke пишет:

Всем спасибо, буду разбираться дальше

разбирайтесь. Код в #17 опять неправильный. Внимательно читайте ответ Евгения в #16 - там изложено два варианта решения.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну амперсанд & и звездочку *  люди иногда путают, особенно если они выполняют не математические действия.

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

Ну амперсанд & и звездочку *  люди иногда путают, особенно если

...особенно когда не понимают, что они означают...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

b707 пишет:

qwone пишет:

Ну амперсанд & и звездочку *  люди иногда путают, особенно если

...особенно когда не понимают, что они означают...

А также наивно полагают, что на "Войну и мир" достаточно одной обезьяны и пары недель времени.

dz4jke
Offline
Зарегистрирован: 01.06.2018

Уважаемые ЕвгенийП и rkit, спасибо вам огромное за то что направили, и извиняюсь если вдруг заставил вас позлиться)) все вчера поправил, как вы сказали, и все заработало, убрал из конструктора функцию colibration(); вынес ее в setup(); чтобы колибровка датчиков происходила после инициализации модуля АЦП, в ином случае все зависало, поэтому я и не сразу понял в чем дело.

#include <Arduino.h>

class PressureSensor
{
public:
    PressureSensor(Adafruit_ADS1115 &ads,uint8_t sensorPin, int16_t sensorMaxRange);
    float getPressureInPsi();
    float getPressureInBar();
    void colibrationSensors();
    
private:
    uint8_t _sensorPin;      // вывод на который подключени датчик давления
    int16_t _sensorMaxRange; // PSI
    uint16_t _sensorAtmosphereADC;
    Adafruit_ADS1115 &_ads;

    uint16_t getADCPressure();
};

PressureSensor::PressureSensor(Adafruit_ADS1115 &ads,uint8_t sensorPin, int16_t sensorMaxRangeInPSI): _ads(ads)
{
    _sensorPin = sensorPin;
    _sensorMaxRange = sensorMaxRangeInPSI;
}

uint16_t PressureSensor::getADCPressure()
{
    uint8_t numSamples = 10;
    uint16_t arrSensorSamples[numSamples];
    uint16_t ResultADC = 0;
    for (uint8_t i = 0; i < numSamples; i++)
    {
        arrSensorSamples[i] = _ads.readADC_SingleEnded(_sensorPin);
    }
    for (uint8_t i = 0; i < numSamples; i++)
    {
        ResultADC += arrSensorSamples[i];
    }
    ResultADC /= numSamples;
    return ResultADC;
}

void PressureSensor::colibrationSensors()
{
    _sensorAtmosphereADC = getADCPressure();
}

float PressureSensor::getPressureInPsi()
{
    float pressure = (float)((int16_t)(getADCPressure() - _sensorAtmosphereADC)) * _sensorMaxRange / (24000 - _sensorAtmosphereADC); // 24000 ADC == 4,5V max range of sensor
    return pressure;
}

float PressureSensor::getPressureInBar()
{
    return 0.06895 * getPressureInPsi();
}

Всем остальным, кто тут вставил свои 5 копеек абы что то сказать, желаю вам обмочиться на людях;)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

dz4jke пишет:

Всем остальным, кто тут вставил свои 5 копеек абы что то сказать, желаю вам обмочиться на людях;)

Пойду людей искать. 

dz4jke
Offline
Зарегистрирован: 01.06.2018

Вам тоже спасибо, я выше вам оставлял благодарность за ваше исправление в моем коде.

"За это исправление спасибо, попробовал, все работает, правда не совсем понял как))"

этот комментарий был для Вас, просто как то не сослался

b707
Offline
Зарегистрирован: 26.05.2017

dz4jke пишет:

Всем остальным, кто тут вставил свои 5 копеек абы что то сказать, желаю вам обмочиться на людях;)

ну раз приглашаешь...

"колибровка" - это что-то про маленьких птичек, как бишь их... колибри?

dz4jke
Offline
Зарегистрирован: 01.06.2018

исправил, на "А", дабы вы не нервничали

кАлибровка*

calibration();

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

тока тип ResultADC смени на uint32_t, иначе на больших значениях работать будет непраильна

uint16_t PressureSensor::getADCPressure()
{
    const uint8_t NUM_SAMPLES = 16;               // количество образцов для массива
    uint32_t ResultADC = 0;                // переменная значений АЦП датчика низкого давления
    /*заполяем массив данных АЦП*/
    for (uint8_t i = 0; i < NUM_SAMPLES; i++) //счетчик заполнения массива АЦП
    {
        ResultADC +=  _ads.readADC_SingleEnded(_sensorPin); //считывание данных АЦП
    }
    return (ResultADC>>4);
}

 

dz4jke
Offline
Зарегистрирован: 01.06.2018

Да да ,я поменял, понял что там переполнение будет

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016