Автор Тема: EC-метр на базе ардуино  (Прочитано 10674 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #30 : 29 Июня 2017, 20:09:40 »
Нет пределов совершенству!
Этот код лишь отправная точка. Дальше можно нарастить все, что угодно. И оптимизировать как угодно.
Но явные ошибки готов выслушать.

Оффлайн Cyclamech

  • Ветеран
  • *****
  • Сообщений: 4502
  • Советский цветовод

  • Активность на форуме
    10.4%
EC-метр на базе ардуино
« Ответ #31 : 29 Июня 2017, 20:22:58 »
Но явные ошибки готов выслушать.
Не могу сказать, явные ли это ошибки ли нет. Для кого как. Попробуем на примере.
Предупрежу: для меня нет разницы между функцией и процедурой, я использую единое понятие - метод. Просто метод может не возвращать ничего (void-метод кагбэ становится процедурой).
Я читаю у Вас: getEC(). Но никакого гетЕС (дай мне значение ЕС!) мы не видим, ибо этот метод возвращает void. *???*
Читаем код метода и встречаем:
Цитировать
EC = 1000/(Rc*K); //получение чистого ЕС
 
 
//*************Компенсация температуры********************//
   EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
   ppm = (EC25)*(PPMconversion*1000); // Переводим получившийся EC в ppm@0,5

//******************Вывод на Экран************************//   
  lcd.setCursor(0,0);
Да, заметно: Вы сами чувствовали, что выходит каша и использовали звёздочки. *crazy*
Надо было просто вернуть "чистое ЕС". Сделать метод терпокомпенсации и метод конвертации ЕС в ппм. Вывод на экран - вообще отдельная тема, м.б., библиотека.

Метод конвертации лучше сразу сделать "универсальным": если язык допускает перегрузку методов, то сделать один метод без параметров, а второй с параметром (коэффициент пересчёта). Из метода без параметра просто вызвать перегруженный, передав параметром константу, в которой "зашито" значение коэффициента перевода по умолчанию - 500. Если перегрузка методов недопустима, сделать 2 метода.
« Последнее редактирование: 29 Июня 2017, 20:33:31 от Cyclamech »
И я теперь учу дневник
Царапин грифельного лета SQM кропкита,
Кремня Воды и воздуха язык,
С прослойкой тьмы, с прослойкой света свiта

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #32 : 29 Июня 2017, 20:40:10 »
Насчет каши категорически не согласен. Всё идёт своим чередом.
Возможно неверно откомментировал. Надо было не "Чистый ЕС", а "Первичный ЕС" назвать.
Конвертацию в ppm изначально делать не хотел. Не особо он и нужен. Но сделал. Без вывода на экран(но с выводом в дебаг).

Оффлайн Cyclamech

  • Ветеран
  • *****
  • Сообщений: 4502
  • Советский цветовод

  • Активность на форуме
    10.4%
EC-метр на базе ардуино
« Ответ #33 : 29 Июня 2017, 20:42:58 »
Насчет каши категорически не согласен.
Как угодно. *???*
Но звёздочки всё равно легко "палят" с потрохами код, стремящийся в кашу. Впрочем, думаю понятно, дело совсем не в звёздочках, а в мысли кодера.
« Последнее редактирование: 29 Июня 2017, 20:45:34 от Cyclamech »
И я теперь учу дневник
Царапин грифельного лета SQM кропкита,
Кремня Воды и воздуха язык,
С прослойкой тьмы, с прослойкой света свiта

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #34 : 29 Июня 2017, 21:02:14 »
Смишной цикламех))) подержи в руках ардуину-то)

Оффлайн Cyclamech

  • Ветеран
  • *****
  • Сообщений: 4502
  • Советский цветовод

  • Активность на форуме
    10.4%
EC-метр на базе ардуино
« Ответ #35 : 29 Июня 2017, 21:17:30 »
Смишной цикламех))) подержи в руках ардуину-то)
Ммм… Эта "кинестетика" точно позволит мне грамотнее писать код?
И я теперь учу дневник
Царапин грифельного лета SQM кропкита,
Кремня Воды и воздуха язык,
С прослойкой тьмы, с прослойкой света свiта

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #36 : 29 Июня 2017, 21:24:21 »
Смишной цикламех))) подержи в руках ардуину-то)
Ммм… Эта "кинестетика" точно позволит мне грамотнее писать код?
Тебе не дано.. *???*

Оффлайн vladindre

  • Постоялец
  • ***
  • Сообщений: 175

  • Активность на форуме
    0%
    • Email
EC-метр на базе ардуино
« Ответ #37 : 29 Июня 2017, 21:27:21 »
Цитировать
масса скетчей для замеров длительности выполнения команд
Хм. Вроде как тривиальный отладчик типа AVR Studio легко указует в боковой панели время выполнения любого куска программы. Хоть в микросекундах , хоть в тактах.

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #38 : 29 Июня 2017, 21:34:32 »
Отредактировал код с учетом справедливых замечаний Vad'a. Действительно немалая экономия памяти получается. В define переводить не стал, т.к. теряется читаемость кода.

ВСЁ! Больше редакций не будет.

Есть желание - делайте, а нет, то х*й с ним *crazy*



#include <OneWire.h> //данная библиотека отредактирована для подключения температурного датчика ds18b20 напрямую(без резисторов). Ссылка на скачивание: [url]https://yadi.sk/d/osXYOMSI3KEThp[/url]
#include <DallasTemperature.h>
#include <EEPROM.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,16,2); //У меня адрес экрана на кв.шине 0x3f, но бывает еще и 0x27, т.е. строка будет выглядеть так 'LiquidCrystal_I2C lcd(0x27,16,2);'

int button = 5;// пин кнопки
boolean buttonState = 0;

int R1 = 510; // R1=510 ом
int R2 = 510;// R2=510 ом
int Ra = 25; //Даже не спрашивайте! Это сопротивление Output цифрового пина на другой цифровой пин, который в состоянии LOW. Rа=V/I(замеряйте, если хотите, сами)
int ECPin = A0;
float TemperatureCoef = 0.019;//темп.коэфф. ~ 2% на градус.
float K = 1.88;//константа первоначальной работы(для американской вилки с дырочками)

float CalibrationEC=2.19; // Здесь Вы задаете EC калибровочного раствора. У меня вода равна 0.19. плюс 1гр соли на 1 литр воды =2ЕС, итого = 2.19

//***********************Остальные переменные**********************************************//

unsigned long int avgValue;


float Temperature=10;
float EC = 0;
float EC25 = 0;
int ppm = 0;
 
 
float raw = 0;
float Vin = 5;
float Vdrop = 0;
float Rc = 0;

//**************************Переменные для Калибровки ******************************************//
float TemperatureFinish=0;
float TemperatureStart=0;
float Kt=0;
 
 
//*********************** Настройки eeprom ******************//
int value;
int addresCalibration=0;


float PPMconversion=0.5;

#define ONE_WIRE_BUS 9          // Сигнальный провод темп. датчика на 9 пине
const int TempProbePossitive =8;  // Плюсовой провод темп.датчика на пине 8
const int TempProbeNegative=7;    //Минусовой провод темп.датчика на пине 7

OneWire oneWire(ONE_WIRE_BUS);// Настраиваем шину
DallasTemperature sensors(&oneWire);// 



void setup() {
               
  Serial.begin(9600);
 
  ADCSRA &= B11111000; //Ускоряем АЦП до 1мГц
  ADCSRA |= B00000100; //-------------//---------------
 
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
 
  pinMode(button, INPUT);
  pinMode(ECPin, INPUT);
 
  pinMode(TempProbeNegative , OUTPUT );
  digitalWrite(TempProbeNegative , LOW );
  pinMode(TempProbePossitive , OUTPUT );
  digitalWrite(TempProbePossitive , HIGH );
 
  delay(100);// даем сенсору время на активацию
  sensors.begin();
  delay(100);
 
  R1=(R1+Ra);

  value = EEPROM.read(addresCalibration);
  if (value <=254) K=value*0.02;
  lcd.init();
  lcd.backlight();
}


 
void loop() {
GetEC();
Calibration();
}

void GetEC(){
  int buf[140],temp;
  sensors.requestTemperatures();// Запрос от датчика температуры
  Temperature=sensors.getTempCByIndex(0); //Запись значений в переменные
 
  for(int i=0;i<140;i++) //берем 140 значений с АЦП
    {
  PORTD = B00000100;
  delayMicroseconds(83); // 83 микросекунды+ускоренный analoread() в течении 17 микросекунд=100микросекунд, что означает 10кГц работы устройства.         
  raw = analogRead(ECPin);
  buf[i] = raw;
  PORTD = B00001000;
  delayMicroseconds(100); //Противофаза, дабы исключить поляризацию.
 
    }
    PORTD = B00000000;
    for(int i=0;i<130;i++)                           
    {
      for(int j=i+1;j<140;j++)
      {
        if(buf[i]>buf[j])
        {
          temp=buf[i];
          buf[i]=buf[j];
          buf[j]=temp;
        }
      }
    }
    avgValue=0;
    for(int i=20;i<100;i++) // 80 средних значений
    avgValue+=buf[i];
    float ECValue=(float)avgValue/80;
   
    Vdrop = (Vin*ECValue)/1024.0; // перевод аналог.значений в милливольты
    Rc = (Vdrop*R1)/(Vin-Vdrop); //Вычисляем сопротивление воды
    Rc = Rc-Ra-R2; // вычитаем лишнее
    EC = 1000/(Rc*K); //получение чистого ЕС
 
 
//*************Компенсация температуры********************//
   EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
   ppm = (EC25)*(PPMconversion*1000); // Переводим получившийся EC в ppm@0,5

//******************Вывод на Экран************************//   
  lcd.setCursor(0,0);
   lcd.print("Arduino EC-PPM   ");
   lcd.setCursor(0,1);
   lcd.print("EC:               ");
   lcd.setCursor(3,1);
    lcd.print(EC25);
   lcd.setCursor(9,1);
    lcd.print(Temperature);
    lcd.print("'C");
//*****************Информация для отладки******************//
Serial.print("EC: ");
Serial.print(EC);
Serial.print(" raw: ");
Serial.print(raw);
Serial.print(" Rc: ");
Serial.print(Rc);
Serial.print(" EC: ");
Serial.print(EC25);
Serial.print(" Simens  ");
Serial.print(ppm);
Serial.print(" ppm  ");
Serial.print(Temperature);
Serial.println(" *C ");
 
//}
}

void Calibration(){
int buf[140],temp;
buttonState = digitalRead(button);
if(buttonState!=HIGH) return;
 
lcd.setCursor(0,0);
lcd.print("Calibrating         ");
lcd.setCursor(0,1);
lcd.print("EC:                 ");
lcd.setCursor(3,1);
lcd.print(CalibrationEC); 
 
sensors.requestTemperatures();
TemperatureStart=sensors.getTempCByIndex(0);

 
//************Estimates Resistance of Liquid ****************//
            for(int i=0;i<140;i++)
    {
  PORTD = B00000100;
  delayMicroseconds(83); // 83 микросекунды+ускоренный analoread() в течении 17 микросекунд=100микросекунд, что означает 10кГц работы устройства.         
  raw = analogRead(ECPin);
  buf[i] = raw;
  PORTD = B00001000;
  delayMicroseconds(100); //Противофаза, дабы исключить поляризацию.
 
    }
    PORTD = B00000000;
   
    for(int i=0;i<130;i++)                            //Сортируем аналоговые значения от меньшего к бОльшему.
    {
      for(int j=i+1;j<140;j++)
      {
        if(buf[i]>buf[j])
        {
          temp=buf[i];
          buf[i]=buf[j];
          buf[j]=temp;
        }
      }
    }
    avgValue=0;
    for(int i=20;i<100;i++)
    avgValue+=buf[i];
    float ECValue=(float)avgValue/80;
           
sensors.requestTemperatures();
TemperatureFinish=sensors.getTempCByIndex(0);
 
 
//*************Компенсация температуры********************//
EC = CalibrationEC*(1+(TemperatureCoef*(TemperatureFinish-25.0))) ;
 
//***************** Вычисление Сопротивления Калибровочного раствора **************************//
Vdrop= (((Vin)*(ECValue))/1024.0);
Rc=(Vdrop*R1)/(Vin-Vdrop);
Rc=Rc-Ra-R2; // вычитаем лишнее
Kt= 1000/(Rc*EC);
 
 
                    if (TemperatureStart==TemperatureFinish){
                      Serial.println("   Results are Trustworthy");
                      Serial.print("Calibration Fluid EC: "); 
                      Serial.print(CalibrationEC);
                      Serial.print(" S  ");  //add units here
                      Serial.print("Cell Constant K");
                      Serial.print(K);
                     
                     
                      lcd.setCursor(0,0);
                      lcd.print("GoodResults         ");
                     
                     
                      lcd.setCursor(0,1);
                      lcd.print("EC:                    ");
                      lcd.setCursor(3,1);
                      lcd.print(CalibrationEC);
                      lcd.setCursor(9,1);
                      lcd.print("K:");
                      lcd.setCursor(11,1);
                      lcd.print(Kt);
                     
                              while (1) {
                             
                             
                              if (buttonState==HIGH){
                               
                               
                              K=Kt; //записываем новую константу
                             
                           //********Запись нового значения в EEPROM**********//   
                            value=K/0.02;
                            EEPROM.write(addresCalibration, value);
 
 
                             
                              lcd.setCursor(0,0);
                              lcd.print("Saved Calibration        ");
                                                           
                              lcd.setCursor(0,1);
                              lcd.print("K:                        ");
                              lcd.setCursor(3,1);
                              lcd.print(Kt);
                              delay(5000);
                              return;
                              }
                             
                             
                             
                               
                              }
                     
                     
                      }
                       
                              else{
                               Serial.println("   Error Wait For Temperature To settle");
                                       
                                        lcd.setCursor(0,0);
                                        lcd.print("Bad Results         ");
                                        delay(5000);
                                        Calibration();
                                       
                            }
 
}

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #39 : 29 Июня 2017, 21:36:53 »
Цитировать
масса скетчей для замеров длительности выполнения команд
Хм. Вроде как тривиальный отладчик типа AVR Studio легко указует в боковой панели время выполнения любого куска программы. Хоть в микросекундах , хоть в тактах.
есть) Вот тока я не пользуюсь AVR Studio))
Обычный IDE.
Ради такой фигни ставить AVR Studio считаю нецелесообразным. Код писался на коленке. Аж целый вечер)))

Оффлайн vladindre

  • Постоялец
  • ***
  • Сообщений: 175

  • Активность на форуме
    0%
    • Email
EC-метр на базе ардуино
« Ответ #40 : 29 Июня 2017, 21:47:40 »
Цитировать
Ради такой фигни ставить AVR Studio считаю нецелесообразным
Ну если не занимаетесь постоянно. Хотя весчь очень сильная.

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #41 : 29 Июня 2017, 21:53:50 »
Цитировать
Ради такой фигни ставить AVR Studio считаю нецелесообразным
Ну если не занимаетесь постоянно. Хотя весчь очень сильная.
Я знаю. Вещь сильная. Изучал мельком.
Но вот не горю я ардуиной. И вообще в последнее время абстрагировался от цифровой техники. Разве только смартфоном и пользуюсь.

Оффлайн vladindre

  • Постоялец
  • ***
  • Сообщений: 175

  • Активность на форуме
    0%
    • Email
EC-метр на базе ардуино
« Ответ #42 : 29 Июня 2017, 22:20:55 »
Цитировать
Разве только смартфоном и пользуюсь.
Страшная вещь. Сверление мозга электромагнитным излучением. Держусь от всего этого за километр.
На работе пытались всучить для работы забесплатно. Отбрыкался таки. Говорю здоровье дороже. Сами сверлитесь.
Посчитайте плотность потока ЭМП в районе мозга. Результат сильно неприятно удивит.

Оффлайн allex_step

  • Ветеран
  • *****
  • Сообщений: 991
  • Хомячина

  • Активность на форуме
    11.2%
    • Email
EC-метр на базе ардуино
« Ответ #43 : 29 Июня 2017, 22:30:28 »
зависит от частоты-активности пользования...


или уходим в холивар?: дышать - вредно, кушать - вредно, да и жить вредно - от этого умирают...

Онлайн Пресвятой_ДжимБим

  • Ветеран
  • *****
  • Сообщений: 871

  • Активность на форуме
    4%
EC-метр на базе ардуино
« Ответ #44 : 29 Июня 2017, 22:39:01 »
А вчем плох смартфон? В интернете полазить, книжку почитать, музычку послушать. Да и по работе..
А поговорить - через блютуз-наушники, или громкую связь в машине.
Этож телефон сотовый..