341 (2017-01-15 23:21:06 отредактировано zcom)

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Все попытки сохранить лог работы внутри Ардуины не увенчались успехом. У Ардуины мало памяти, так что актуален только вариант с выгрузкой данных в режиме реального времени. Программы протоколлирования сом-порта необходимы. Я снимаю лог (формат csv) Arduino IDE, затем все копирую, сохраняю в текстовый файл, загужаю в Excell. Там уже и графики можно строить, и анализировать.

342

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

zcom ©:

....Финальная на сегодня доработка скетча.....

Скетч из сообщения копируется с ошибками, ручками я его конечно поправил, как смог, но удобнее было бы на яндекс диск, а сюда ссылку, если правила позволяют. Еще бы  сразу к нему и схему подключения приложить, таким как я, "ардунщикам" в кавычках, очень бы помогло. Нет, я конечно в иззвестном слове из трех букв, три ошибки не делаю, но ардуинка для меня пока "темный лес", впрочем как и винокурение.ИМХО

Справедливость проявляется в воздаянии каждому по его заслугам.
                                                                                                            Цицерон

343

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Толян ©:
zcom ©:

....Финальная на сегодня доработка скетча.....

Скетч из сообщения копируется с ошибками

С ошибками? Странно, конечно. Может не все копируете? Или, наоборот, что-то лишнее прихватывается? Вот, проверенный вариант. На днях появится обновленный вариант для измененной БК с черновым расчетом поглощаемого димротом тепла в реальном времени. Не знаю, на сколько этот расчет будет соответствовать действительности, но хотя бы в первом приближении будет интересно посмотреть.

#include <OneWire.h>
#include <memorysaver.h>
#include <UTFT.h>

#define PIN_CONNECT     10          // on pin 10 (a 4.7K resistor is necessary)
#define SERIAL_BAUD     115200      //
#define TS_PERIOD       1000        // 
#define TS_RESOLUTION   12          // 9, 10, 11, 12 bit
#define SENSORS         6           //

#define TOP_COLUMN      "28.F6.29.01.00.00.80.D6"
#define MIDDLE_COLUMN   "28.F5.33.01.00.00.80.4E"
#define IN_WATER        "28.B2.34.01.00.00.80.EF"
#define IN_DIMROT       "28.13.29.01.00.00.80.14"
#define OUT_DIMROT      "28.F4.DF.00.00.00.80.0D"
#define FREE_TS         "28.12.29.01.00.00.80.23"

extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

struct tsdata {
  byte addr[8];
  byte answer[9];
  float tempC = -273.15;
  float tempF = -273.15;
  boolean enable = false;
  boolean readable = false;
};
tsdata ts[SENSORS];
float tempC[SENSORS];
unsigned long count = 0;
byte operation = 1;

OneWire ds(PIN_CONNECT);  
UTFT    LCD(CTE32HR, 38, 39, 40, 41);

// from http://forum.arduino.cc/index.php?topic=37391.0 #9
char * floatToString(char * outstr, double val, byte precision, byte widthp){
 char temp[16]; //increase this if you need more digits than 15
 byte i;

 temp[0]='\0';
 outstr[0]='\0';

 if(val < 0.0){
   strcpy(outstr,"-\0");  //print "-" sign
   val *= -1;
 }

 if( precision == 0) {
   strcat(outstr, ltoa(round(val),temp,10));  //prints the int part
 }
 else {
   unsigned long frac, mult = 1;
   byte padding = precision-1;
   
   while (precision--)
     mult *= 10;

   val += 0.5/(float)mult;      // compute rounding factor
   
   strcat(outstr, ltoa(floor(val),temp,10));  //prints the integer part without rounding
   strcat(outstr, ".\0"); // print the decimal point

   frac = (val - floor(val)) * mult;

   unsigned long frac1 = frac;

   while(frac1 /= 10) 
     padding--;

   while(padding--) 
     strcat(outstr,"0\0");    // print padding zeros

   strcat(outstr,ltoa(frac,temp,10));  // print fraction part
 }

 // generate width space padding 
 if ((widthp != 0)&&(widthp >= strlen(outstr))){
   byte J=0;
   J = widthp - strlen(outstr);

   for (i=0; i< J; i++) {
     temp[i] = ' ';
   }

   temp[i++] = '\0';
   strcat(temp,outstr);
   strcpy(outstr,temp);
 }

 return outstr;
}

char * ts_addr(char * outstr, byte i) {
  sprintf(outstr, "%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", ts[i].addr[0], ts[i].addr[1],  ts[i].addr[2], ts[i].addr[3], ts[i].addr[4], ts[i].addr[5], ts[i].addr[6], ts[i].addr[7]);
  return outstr;
}

char * ts_name(byte i, boolean shortName=false) {
  char temp[22];

  ts_addr(temp, i);
  if (strcmp(temp, TOP_COLUMN)==0) {
    if (shortName)
      return "TOP";
    else
      return "top column";
  }
  if (strcmp(temp, MIDDLE_COLUMN)==0) {
    if (shortName)
      return "2/3";
    else
      return "2/3 column";
  }
  if (strcmp(temp, IN_WATER)==0) {
    if (shortName)
      return "WATER";
    else
      return "input water";
  }
  if (strcmp(temp, IN_DIMROT)==0) {
    if (shortName)
      return "DIMROT";
    else
      return "input dimrot";
  }
  if (strcmp(temp, OUT_DIMROT)==0) {
    if (shortName)
      return "outWATER";
    else
      return "output dimrot";
  }
  if (strcmp(temp, FREE_TS)==0) {
    if (shortName)
      return "FREE";
    else
      return "free sensor";
  }
  return '\0';
}

void ts_output_all_address(boolean s=true) {
  byte i;
  char temp[22];
   
  for (i=0; i<SENSORS; i++) {
    if (ts[i].enable) {
      Serial.print("Device ");
      Serial.print(i);
      Serial.print(" = ");
      Serial.println(ts_addr(temp, i));
    }
  }
}

void ts_init(boolean showMenu=true) {
  byte i, j, n=0;
  char temp[22];

  ds.reset_search();
  while (ds.search(ts[n].addr)) {
    if (ds.crc8(ts[n].addr, 7) == ts[n].addr[7]) {
      if ((ts[n].addr[0] == 0x10) || (ts[n].addr[0] == 0x22) || (ts[n].addr[0] == 0x28)) {
        ts[n].enable = true;
        ds.reset();
        ds.select(ts[n].addr);
        ds.write(0x4E);
        ds.write(0);
        ds.write(0);
        switch (TS_RESOLUTION) {
          case 9:
            ds.write(0x1F);
          case 10:
            ds.write(0x3F);
          case 11:
            ds.write(0x5F);
          default:
            ds.write(0x7F);
        }
        ds.write(0x48);
        n++;
        if (n > SENSORS)
          break;
      }
    }
  }
  if (showMenu) {
    Serial.print("Number of sensors = ");
    Serial.println(n);
    for (i=0; i<SENSORS; i++) {
      if (ts[i].enable) {
        Serial.print("Device ");
        Serial.print(i);
        Serial.print(" = ");
        Serial.println(ts_addr(temp, i));
      }
    }
    if (n != 0) {
      Serial.println("Menu:");
      Serial.println("1 - Starts measurement");
      Serial.println("2 - Starts diagnostics");
      Serial.println("3 - Show sensors address");
      Serial.println("0 - To stop all operations");
      Serial.println("Choice?");
    }
  }
}

void ts_conv(void) {
  byte i;
  
  for (i=0; i<SENSORS; i++) {
    if (ts[i].enable) {
      ts[i].readable = false;
      ds.reset();
      ds.select(ts[i].addr);
      ds.write(0x44);
    }
  }
}

void ts_read(void) {
  byte i, j;
  int16_t test;
  float tC;

  for (i=0; i<SENSORS; i++) {
    if (ts[i].enable) {
      ds.reset();
      ds.select(ts[i].addr);
      ds.write(0xBE);
      for (j=0; j<9; j++) {
        ts[i].answer[j] = ds.read();
      }
      ts[i].readable = (ds.crc8(ts[i].answer, 8) == ts[i].answer[8]);
      test = ts[i].answer[1] * 256 + ts[i].answer[0];
      if (ts[i].addr[0] == 0x10) {
        test = test << 3;
        if (ts[i].answer[7] == 0x10) {
          test = (test & 0xFFF0) + 12 - ts[i].answer[6];
        }
      }
      else {
        switch (ts[i].answer[4] & 0x60) {
          case 0x00:
            test = test & ~7;
          case 0x20:
            test = test & ~3;
          case 0x40:
            test = test & ~1;
        }
      }
      ts[i].tempC = (float)test / 16.0;
      ts[i].tempF = ts[i].tempC * 1.8 + 32.0;
    }
  }
}

void ts_diag(void) {
  byte i;
  char temp[22];

  for (i=0; i<SENSORS; i++)
    if (abs(ts[i].tempC - tempC[i]) >= 5) {
      Serial.print("Device ");
      Serial.print(i);
      Serial.print(" = ");
      Serial.println(ts_addr(temp, i));
      Serial.print(", resting temperature = ");
      Serial.print(tempC[i]);
      Serial.print("C, current temperature = ");
      Serial.print(ts[i].tempC);
      Serial.println("C");
    }
}

void ts_output_serial(void) {
  byte i;
  
  Serial.print("ts_data,");
  Serial.print(millis());
  for (i=0; i<SENSORS; i++) {
    if (ts[i].enable) {
      Serial.print(",");
      Serial.print(ts[i].tempC);
    }
  }
  Serial.println();
}

void lcd_init(void) {
  LCD.InitLCD(0);
  LCD.clrScr();
}

void ts_output_lcd(void) {
  byte i, b;
  char text[7], buf[4], temp[22];;
  int y;

  LCD.setFont(BigFont);
  LCD.print("Temperature", LEFT, 20);
  for (i=0; i<SENSORS; i++) {
    if (ts[i].enable) {
      ts_addr(temp, i);
      if (strcmp(temp, TOP_COLUMN)==0)
        y = 50;
      else if (strcmp(temp, MIDDLE_COLUMN)==0)
        y = 105;
      else if (strcmp(temp, IN_WATER)==0)
        y = 170;
      else if (strcmp(temp, IN_DIMROT)==0)
        y = 225;
      else if (strcmp(temp, OUT_DIMROT)==0)
        y = 280;
      else if (strcmp(temp, FREE_TS)==0)
        y = 335;
      else
        y = 390;
      LCD.setFont(SevenSegNumFont);
      floatToString(text, ts[i].tempC, 2, 6);
      if (text[0] = 32) {
        buf[0] = text[1];
        buf[1] = text[2];
        buf[2] = '\0';
        LCD.print(buf, 32, y);
      }
      else if (text[0] = '-') {
          buf[0] = text[1];
          buf[1] = text[2];
          buf[2] = '\0';
          LCD.print(buf, 32, y);
      }
      else {
          buf[0] = text[0];
          buf[1] = text[1];
          buf[2] = text[2];
          buf[3] = '\0';
          LCD.print(buf, 0, y);
      }
      LCD.fillRect(102, y + 43, 106, y + 48);
      buf[0] = text[4];
      buf[1] = text[5];
      buf[2] = '\0';
      LCD.print(buf, 112, y);
      LCD.setFont(BigFont);
      LCD.print("ts", 184, y);
      text[0] = char(49 + i);
      text[1] = '\0';
      LCD.print(text, 216, y);
      LCD.print(ts_name(i, true), 184, y + 34);
    }
  }
}

void setup(void) {
  Serial.begin(SERIAL_BAUD);

  lcd_init();
  ts_init(false);
  ts_conv();
  count = millis();
}

void loop(void) {
  byte i, data;
  char temp[22], text[7];

  data = Serial.read();
  if (data == 0x30) {
    operation = 0;
    Serial.println("Break of operation");
    ts_init();
  } 
  else if (data == 0x31) {
    operation = 1;
    lcd_init();
    Serial.println("Running measurement");
  }
  else if (data == 0x32) {
    operation = 2;
    lcd_init();
    Serial.println("Running diagnostics");
    ts_read();
    for (i=0; i<SENSORS; i++)
      tempC[i] = ts[i].tempC;
  }
  else if (data == 0x33) {
    operation = 3;
    // Output serial
    Serial.println("Show sensors address");
    for (i=0; i<SENSORS; i++) {
      if (ts[i].enable) {
        Serial.print("Device ");
        Serial.print(i);
        Serial.print(" = ");
        Serial.print(ts_addr(temp, i));
        Serial.print(", ");
        Serial.println(ts_name(i));
      }
    }
    // Output lcd
    lcd_init();
    for (i=0; i<SENSORS; i++) {
      if (ts[i].enable) {
        LCD.setFont(BigFont);
        LCD.print("ts =", 0, 30 + i*20);
        text[0] = char(49 + i);
        text[1] = '\0';
        LCD.print(text, 32, 30 + i*20);
        LCD.print(ts_addr(temp, i), 70, 30 + i*20);
      }
    }
  }

  if (operation == 1) 
    if ((millis() - count) >= TS_PERIOD) {
      count = millis();
      ts_read();
      ts_output_serial();
      ts_output_lcd();
      ts_conv();
    }
  if (operation == 2) 
    if ((millis() - count) >= TS_PERIOD) {
      count = millis();
      ts_read();
      ts_diag();
      ts_conv();
    }
}

Вопросы по коду задавайте, отвечу.

Толян ©:

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

Схему надо нарисовать. Тут вы правы. Но ее пока нет. :) Словесное описание.  Я использую Arduino Due, схема и скетч подойдет и для Arduino Mega2560. Используется сама тушка, на нее одевается TFT-дисплей 480х320 точек (покупал в Амперке, он там один такой). Далее на 10 контакт PWM одевается проводник, соединяются сигнальные линии всех датчиков температуры в одну линию, подключаются к этому проводнику. Далее с платы Ардуины забираю "землю" (GND) и питание (+3,3В для Due и +5 для Mega2560). Также соответствующие провода датчиков в одну шину и к ним питание и землю. Между сигнальным проводом и питанием припаиваем резистор на 4,7кОм. Вроде как все.
Недостающие библиотеки для скетча скачиваем с github. Ищем через google, например.

Это общий вид сборки без датчиков. Датчики подключаются через разъемы.

Вот монтажная плата с разъемами и резистором.

Это уже готовый к работе вариант. Тоже без датчиков (просто они на колонне закреплены, не снять просто так).

344

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

zcom ©:

С ошибками? Странно, конечно. Может не все копируете?...

Копирую все, но для примера, после копирования, вместо кавычек, автоматом ставит буквы с символами.

Справедливость проявляется в воздаянии каждому по его заслугам.
                                                                                                            Цицерон

345 (2017-01-24 01:26:38 отредактировано zcom)

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Толян ©:
zcom ©:

С ошибками? Странно, конечно. Может не все копируете?...

Копирую все, но для примера, после копирования, вместо кавычек, автоматом ставит буквы с символами.

Понял. Проблема именно в копировании.... https://yadi.sk/d/zhFjOAM-3AYEMY
Я сейчас в процессе понимания как Ардуиной еще мощностью нагрева тэна управлять. Так, чтобы не Ардуина постоянно по прерываниям симистор открывала, а, например, при помощи цифрового потенциометра, встроенного в цепь вместо ручного. Она его значение раз в секунду изменяла и не отвлекалась более на это. Но точность оставляет желать лучшего из-за разброса параметров других компонент, хотя... калибровка... Пока в железе еще не повторил. Прототипы с ручным управлением есть.

P.S. Вышеописанная задача с цифровым потенциометром больше теоретическая. Мощности Ардуины достаточно для отработки всех задач, если грамотно обрабатывать прерывания. Просто с цифровым потенциометром становится возможным управлять тэнами с абсолютно любого устройства, просто отдавая команды, а не контролируя процесс.

346 (2017-01-24 02:51:43 отредактировано Kreg1969)

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

zcom ©:

Да, думал об этом. С реальным временем сложно - нужен его источник. В Ардуине своих часов нет. Но можно использовать момент времени с начала запуска контроллера. Формат CSV. Его легко импортировать хоть в Excell, хоть в СУБД.

Так существуют же модули часов реального времени для ардуинки...

zcom ©:

Так, чтобы не Ардуина постоянно по прерываниям симистор открывала, а, например, при помощи цифрового потенциометра, встроенного в цепь вместо ручного.

Если строить управление мощностью на твердотельном реле, то может проще взять реле с управлением не по сопротивлению а по напряжению? Там правда придется какой то преобразователь управляющего сигнала городить, если мне память не изменяет, то диапазон управляющего напряжения для реле от 3 до 32 вольт.

Jedem das Seine
Дистилятор с укреплением 15\650 медь
РК 28\1300 медь
Учиться - никогда не поздно

347

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Я пробовал. ТТ по напряжению не работает как симистор. Только вкл- выкл. Нужно что то другое, чтобы например ШИМ управлялось. Чисто теоретически (сам не пробовал) можно поставить мост и управлять мощным транзистором мосфетом. Он может плавно открываться.
Как вариант использовать ПИД регулятор. На ардуинке он тоже реализуется.

Ленивые всё делают быстро, что бы скорее отделаться от работы и делают хорошо, чтобы не переделывать.
С уважением, Николай.
Моё оборудование : → Винокурня Николя

348

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Очередное продолжение версии что в начале темы на дисплее  0.96" IIC/I2C 128x64 OLED
Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

На дисплей выводятся показания 4х датчиков ds18b20 и давления BMP 180
Код по ссылке  https://drive.google.com/file/d/0B5BI-x … sp=sharing

Ленивые всё делают быстро, что бы скорее отделаться от работы и делают хорошо, чтобы не переделывать.
С уважением, Николай.
Моё оборудование : → Винокурня Николя

349

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Надоело мне постоянно вытаскивать из корпуса потроха блока, переделываю постоянно, экспериментирую.
Сделал просто на платформе, что бы все доступно.
Здесь еще дисплей Nextion прикручен.
Так как все мое хозяйство в подвале, очень не удобно постоянно туда нырять. Вывел я на него показания с колонны и заодно управление котлом отопления. Сейчас все тестируется, интерфейс простенький написал. Как все отлажу можно и украшательством заняться.

   

Ленивые всё делают быстро, что бы скорее отделаться от работы и делают хорошо, чтобы не переделывать.
С уважением, Николай.
Моё оборудование : → Винокурня Николя

350

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Николя, ну... руки-то золотые!
Вот и нет покоя!!  *THUMBSUP*
Завидую!!!  :rolleyes:

351

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Прям рок какой то преследует! Вчера собрал все это в кучу, повесил на стенку. Поставил перегонять чачу. 20 литров. Ну думаю пока гонится другие дела поделаю. Ага, сейчас! Полез провод поправить, и коротнул! Все выгорело. Гнал в ручном режиме. И дела толком не поделал!

Ленивые всё делают быстро, что бы скорее отделаться от работы и делают хорошо, чтобы не переделывать.
С уважением, Николай.
Моё оборудование : → Винокурня Николя

352

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Николя

Здравствуйте.
Заинтересовал ваш проект, есть желание повторить его.
Не поделитесь материалами для самостоятельной сборки (имеется в виду список деталей примененных и прошивки для ардуины и т.п.)?

353

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

munshainer ©:

Не поделитесь материалами для самостоятельной сборки

Елы палы, нет сил даже первую страницу темы прочитать?

354 (2017-04-01 22:20:57 отредактировано geha69)

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

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

Иван Николаевич не будет против такая заставка может быть при загрузке устройства

страница настроек

какие есть предложения.

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

355

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Дисплей Nextion?
Удобный. Сейчас тоже иногда мучаю его, времени не хватает довести до ума.

Ленивые всё делают быстро, что бы скорее отделаться от работы и делают хорошо, чтобы не переделывать.
С уважением, Николай.
Моё оборудование : → Винокурня Николя

356 (2017-04-02 10:10:12 отредактировано Saks)

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Добрый день! 

geha69 ©:

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

  Геннадий,подскажи пожалуйста где приобрел этот удобный девайс.

Успех-это умение двигаться от неудачи к неудаче, не теряя энтузиазма.

357

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

geha69 ©:

какие есть предложения.

Собрать в один пост (можно и в отдельный) описание прибора с алгоритмом работы и если не жалко, дать людям скетч :)

У вас в жизни всегда будет все, что вы хотите, если вы будете помогать другим людям получать то, чего хотят они.
Регистрация на форуме отключает почти всю рекламу.

358 (2017-04-02 12:58:55 отредактировано geha69)

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Здравия Всем!Иван Николаевич скеча не жалко.алгоритм работы схожий с предэдущей моей конструкцией,c некоторыми доработками (задержка открытия клапана после превышения температуры,можно также рег.мощн.сделать фазовой,можно шим).также в ручном режиме можно клапан открыть закрыть тэн вкл. выкл.и стабилизацию вкл выкл подлительному нажатию кн. стаб более 3 сек.я не програмист поэтому у меня все не очень быстро происходит.когда проэкт будет испытан в железе все будет доступно в публичном доступе с описанием.еще планирую время задержки откр. клапана сделать регулируемым, каждый сможет задержку откр клап под свой агрегат установить.да забыл сказать панель Nextion HMI 400+240 (наверное ближе 3.2 дюйма)

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

359

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

У меня сейчас примерно так выглядит

Ленивые всё делают быстро, что бы скорее отделаться от работы и делают хорошо, чтобы не переделывать.
С уважением, Николай.
Моё оборудование : → Винокурня Николя

360

Re: Автоматика на Arduino для ректификации и дистилляции (схема-прошивки)

Я у себя сделал такой тестовый интерфейс. Температура кипения рассчитывается автоматом, напряжение на ТЭН задается через всплывающее меню, можно настроить любую логику по имеющимся датчикам и исполнительным устройствам.
Испытал на добыче СС, все вроде работает.