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

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

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

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

Оффлайн Cyclamech

  • Ветеран
  • *****
  • Сообщений: 4648
  • Советский цветовод
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тла

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

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

Оффлайн Cyclamech

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

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

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

Оффлайн Cyclamech

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

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

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

Оффлайн vladindre

  • Постоялец
  • ***
  • Сообщений: 175
    • Email
EC-метр на базе ардуино
« Ответ #37 : 29 Июня 2017, 21:27:21 »
Цитировать (выделенное)
масса скетчей для замеров длительности выполнения команд
Хм. Вроде как тривиальный отладчик типа AVR Studio легко указует в боковой панели время выполнения любого куска программы. Хоть в микросекундах , хоть в тактах.

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

  • Ветеран
  • *****
  • Сообщений: 826
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();
                                       
                            }
 
}

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

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

Оффлайн vladindre

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

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

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

Оффлайн vladindre

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

Оффлайн allex_step

  • Ветеран
  • *****
  • Сообщений: 1120
  • Хомячина
    • Email
EC-метр на базе ардуино
« Ответ #43 : 29 Июня 2017, 22:30:28 »
зависит от частоты-активности пользования...


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

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

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