Форум самогонщиков Сайт Барахолка Магазин Помощь солдатам

Аппаратная платформа Arduino для автоматизации наших процессов

Форум самогонщиков Автоматика
1 ... 28 29 30 31 32 33 34 ... 66 31
alekslug Научный сотрудник винокур, Лобня. 5.2K 1.7K
Отв.600  29 Окт. 13, 12:45
Попытался научить русскому языку свой Arduino Mega 2560,  ЖК индикатор WH1602BYYK-CTK по ссылке загрузив библиотеку [сообщение #11375772]  -  не получается. Библиотека загрузилась, но не работает.
Помогите настроить. Я индикатор и спиртом протирал и огурчик соленый  ему предлагал - не помогает.
asvar Специалист Крога 163 30
Отв.601  29 Окт. 13, 12:51, через 7 мин
я парился долго, но тоже так и не одолел, видать такая разновидность экрана.
делал иначе, но правда дополнительные телодвижения нужны. Не помню где это нашел, тачка не моя, но работает
//-----------------------------------------------------------------
//Кусок кода отвечающий за русскую трансляцию букв
//Для вывода на дисплей русских символов используйте функцию
//printToScreen("", "") первый аргумент - верхняя строка, второй - нижняя
//Ахтунг! Не используйте маленькие буквы "ё" и "с",
//их коды в младшей части совпадают с буквами 'Б' и 'Е'
//из-за отсутствияих нормальной работы с юникодом не представляю как это поправить
//-----------------------------------------------------------------

//Список загруженных недостающих букв
char loadedLetters[9];
//Русская кодировка недостающих букв
//В двоичном виде получается наглядно отобразить очертание символов,
//но получается очень длинная портянка, поэтому сделал в HEX
byte rusLetterB[8]  = {0x1F,0x11,0x10,0x1E,0x11,0x11,0x1E,0};    //Б
byte rusLetterG[8]  = {0x1F,0x11,0x10,0x10,0x10,0x10,0x10,0};    //Г
byte rusLetterD[8]  = {0x0F,0x05,0x05,0x05,0x09,0x11,0x1F,0x11}; //Д
byte rusLetterGH[8]  = {0x15,0x15,0x15,0x0E,0x15,0x15,0x15,0};    //Ж
byte rusLetterI[8]  = {0x11,0x11,0x13,0x15,0x19,0x11,0x11,0};    //И
byte rusLetterIY[8]  = {0x0A,0x15,0x13,0x15,0x19,0x11,0x11,0};    //Й
byte rusLetterL[8]  = {0x0F,0x05,0x05,0x05,0x05,0x15,0x09,0};    //Л
byte rusLetterP[8]  = {0x1F,0x11,0x11,0x11,0x11,0x11,0x11,0};    //П
byte rusLetterF[8]  = {0x04,0x0E,0x15,0x15,0x15,0x0E,0x04,0};    //Ф
byte rusLetterC[8]  = {0x11,0x11,0x11,0x11,0x11,0x11,0x1F,1};    //Ц
byte rusLetterCH[8]  = {0x11,0x11,0x11,0x0F,0x01,0x01,0x01,0};    //Ч
byte rusLetterSH[8]  = {0x15,0x15,0x15,0x15,0x15,0x15,0x1F,0};    //Ш
byte rusLetterSCH[8] = {0x15,0x15,0x15,0x15,0x15,0x15,0x1F,1};    //Щ
byte rusLetterTZN[8] = {0x18,0x08,0x08,0x0E,0x09,0x09,0x0E,0};    //Ъ
byte rusLetterEI[8]  = {0x11,0x11,0x11,0x19,0x15,0x15,0x19,0};    //Ы
byte rusLetterEE[8]  = {0x0E,0x11,0x01,0x07,0x01,0x11,0x0E,0};    //Э
byte rusLetterYU[8]  = {0x12,0x15,0x15,0x1D,0x15,0x15,0x12,0};    //Ю
byte rusLetterYA[8]  = {0x0F,0x11,0x11,0x0F,0x05,0x09,0x11,0};    //Я

//Функция ищет символ среди дополнительно загруженных (максимум Крутой,
//при необходимости и если есть место символ загружается в LCD
char loadAndGetChar(char c, uint8_t *letterMap) {
  int ix = 9;
  //Ищем букву в уже загруженных символах
  for (int i = 1; i < ix; i++) {
    if (c == loadedLetters) {
      return char(i);
    }
    else if (loadedLetters == ' ') {
      ix = i;
      break;
    }
  }
  //Если загружено 8 символов, то выводим пробел
  if (ix == 9) {
    return ' ';
  }
  //Загружаем новый символ в LCD
  lcd.createChar(ix, letterMap);
  loadedLetters[ix] = c;
  return char(ix);
}

//Функция возвращает локализованный символ или пробел,
//если не хватает места в памяти под дополнительные символы
char getTranslatedLetter(char c) {
  switch (c) {
    case 'А' : case 'а' : return 'A';
    case 'Б' : case 'б' : return loadAndGetChar(c, rusLetterB);
    case 'В' : case 'в' : return 'B';
    case 'Г' : case 'г' : return loadAndGetChar(c, rusLetterG);
    case 'Д' : case 'д' : return loadAndGetChar(c, rusLetterD);
    case 'Е' : case 'е' : return 'E';
    case 'Ё' : return 'E';
    case 'Ж' : case 'ж' : return loadAndGetChar(c, rusLetterGH);
    case 'З' : case 'з' : return '3';
    case 'И' : case 'и' : return loadAndGetChar(c, rusLetterI);
    case 'Й' : case 'й' : return loadAndGetChar(c, rusLetterIY);
    case 'К' : case 'к' : return 'K';
    case 'Л' : case 'л' : return loadAndGetChar(c, rusLetterL);
    case 'М' : case 'м' : return 'M';
    case 'Н' : case 'н' : return 'H';
    case 'О' : case 'о' : return 'O';
    case 'П' : case 'п' : return loadAndGetChar(c, rusLetterP);
    case 'Р' : case 'р' : return 'P';
    case 'С' : return 'C';
    case 'Т' : case 'т' : return 'T';
    case 'У' : case 'у' : return 'y';
    case 'Ф' : case 'ф' : return loadAndGetChar(c, rusLetterF);
    case 'Х' : case 'х' : return 'X';
    case 'Ц' : case 'ц' : return loadAndGetChar(c, rusLetterC);
    case 'Ч' : case 'ч' : return loadAndGetChar(c, rusLetterCH);
    case 'Ш' : case 'ш' : return loadAndGetChar(c, rusLetterSH);
    case 'Щ' : case 'щ' : return loadAndGetChar(c, rusLetterSCH);
    case 'Ъ' : case 'ъ' : return loadAndGetChar(c, rusLetterTZN);
    case 'Ы' : case 'ы' : return loadAndGetChar(c, rusLetterEI);
    case 'Ь' : case 'ь' : return 'b';
    case 'Э' : case 'э' : return loadAndGetChar(c, rusLetterEE);
    case 'Ю' : case 'ю' : return loadAndGetChar(c, rusLetterYU);
    case 'Я' : case 'я' : return loadAndGetChar(c, rusLetterYA);
    default  : return c;
  }
}

//Функция печатает верхнюю и нижнюю строку на LCD
void printToScreen(char *st1, char *st2) {
  //Очистка списка загруженных кастомных символов
  for (int i = 0; i < 9; i++) loadedLetters = ' ';
  //Печать первой строки
  char result1[17] = "                "; int ix = 0;
  for (int i = 0; i < 32; i++) {
    char c = getTranslatedLetter(st1);
    if (byte(c) == 0) break;
    else if (byte(c) != 0xD0 && byte(c) != 0xD1) {
      result1[ix] = c;
      ix++;
    }
  }
  lcd.setCursor(0,0);
  lcd.print(result1);
 
  //Печать второй строки
  char result2[17] = "                "; ix = 0;
  for (int i = 0; i < 32; i++) {     
    char c = getTranslatedLetter(st2);
    if (byte(c) == 0) break;
    else if (byte(c) != 0xD0 && byte(c) != 0xD1) {
      result2[ix] = c;
      ix++;
    }
  }
  lcd.setCursor(0,1);
  lcd.print(result2);
}
//-----------------------------------------------------------------
//Конец кода отвечающего за русскую трансляцию букв
//-----------------------------------------------------------------

Потом в коде вывод на экран делаю функцией printToScreen("НАЖМИТЕ КНОПКУ", "ВВЕРХ");
Может кто доведёт до ума и сделает этот как библиотеку, но мои знания это не позволяют.
alekslug Научный сотрудник винокур, Лобня. 5.2K 1.7K
Отв.602  29 Окт. 13, 20:16
Частично можно решить эту задачу.
#include <LiquidCrystal.h>

//Создаем объект для работы с дисплеем.
//При создании указываем номера портов
//в порядке RS, E, DB4, DB5, DB6, DB7
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  //Выставлем число столбцов и строк
  lcd.begin(16, 2);
  //Выводим текст
  lcd.print("\240\341\241\261\340\242\243\244\246\252\260\342\247\250\251\255");
}

void loop() {
  //Выставляем курсор во 2-ю строку,
  //1й столбец (счет идет с 0, поэтому
  //строка номер 1, стобец номер 0)
  lcd.setCursor(0, 1);
  //Выводим число секунд со старта
  lcd.print(millis()/1000);
}

alekslug Научный сотрудник винокур, Лобня. 5.2K 1.7K
Отв.603  29 Окт. 13, 21:22
Калибруем кнопки. Русский шрифт.
#include <LiquidCrystal.h> //подключаем библиотеку работы с ЖКИ

// инициализация библиотеки дисплея. Аргументы - пины на которые подключен LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int butPin = 0;            // вход кнопок
int butPush = 0;            // код нажатой кнопки

void setup() {
  // говорим сколько строк и столбцов в нашем дисплее
  lcd.begin(16, 2);
  lcd.print("P\251CCK\245\246 \254P\245\252T");   // печатаем строку
  delay(5000);  // ждем 2 секунды
  lcd.clear();  // очищаем дисплей
  lcd.print("KA\247\245\240P\251EM KHO\250K\245");  // печатаем строку
}

void loop() {
  lcd.setCursor(0,1); // устанавливаем курсор во вторую строку
  lcd.print(analogRead(butPin)); //печатаем значение возвращаемое функцией analogRead
  // значение от 0 до 1023 пропорционально поданному напряжению
  lcd.print("   "); // строка пробелов нужна чтобы затереть символы от предыдущего замера если
  // текущее значение имеет меньше знаков чем прошлое
  delay(100); // задержка в 0,1 секунды
}

KD Научный сотрудник Танкоград 1.4K 648
Отв.604  07 Нояб. 13, 14:30
немного дополню
далеко не всегда дисплей имеет набор кириллических символов
метод предложенный asvar позволяет загрузить недостающие символы в контроллер дисплея, соответственно работать будет с любым экранчиком.
в коде что приводит alekslug подразумевается что символы уже есть (сообщается из код).
alekslug, твой дисплей, судя по маркировке, должен поддерживать кириллицу.
alekslug Научный сотрудник винокур, Лобня. 5.2K 1.7K
Отв.605  07 Нояб. 13, 15:03, через 34 мин
Да,  WH1602B-YYK-CTK кириллицу поддерживает.  Знаний пока не хватает.
asvar Специалист Крога 163 30
Отв.606  18 Нояб. 13, 15:25
По времени. Если через 15 минут температура не вернулась на исходную позицию процесс надо закончить.alekslug, 23 Окт. 13, 15:46
На выходных тестировал дописанный код, ректифицировал 27л 40% сэма. Выяснилось что ждать СТОПа длительностью 15 минут и более смысла нет. Я остановился на 8 минутах. Пока думаю есть ли в этом смысл, т.к отбор в самом конце процесса уменьшается очень сильно, стоит ли морочить голову пару часов за пол литра спирта.
Вобщем, всё получается отлично, для своей колонны в скором будущем допишу полный автомат ректификации (очень надеюсь).
alekslug Научный сотрудник винокур, Лобня. 5.2K 1.7K
Отв.607  18 Нояб. 13, 18:50
asvar,скетчем поделишься?, мне ещё далеко до результата. Програмист из меня пока плохой. Обычно я заканчиваю процесс ректификации при Т. в кубе 96*С , что соответствует  остатку спирта в кубе несколько процентов, переводом колонны на режим дистилляции хвостов. Т.е. нагрев и отбор на полную мощность включаю. Но иногда может понадобиться режим ректификации до упора, до полного истощения спирта из куба и  колонны. Ардуино позволяет гибко подойти к решению этого вопроса. Колонны могут быть разной  производительности. Имеет смысл заложить в программу регулировать этот параметр.
   
asvar Специалист Крога 163 30
Отв.608  19 Нояб. 13, 18:58
Из меня программист не лучше. Скетч вылаживаю. Но после последней ректификации уже пишу код дальше, но выложу по итогам.
По тому что выкладываю - пока регулировка отбора и мощности руками (записываю показания с экрана, потом буду их вводить из меню с возможностью изменения). Регулирую мощность один раз, после разгона колоны, уменьшаю крутилкой до величины подобраной эксперементально, всё про мощность на этом забываю.
По клапану отбора - кручу его 2 раза. Первый - после работы колонны на себя, также устанавливаю эксперементально подобраную величину (100мл/ч) и иду спать. Просыпаюсь - головы вот-вот отберуться, нюхаю всё проверяю, меняю тару.
Второй раз - для отбора тела (так же эксперементально подобранная величина +- 1400мл/час).
Всё дальше можно отдыхать.
Что есть: проверка на аварию в дефлегматоре, если затоп - выключаем нагрев. Режим СТАРТ/СТОП - при достижении в 20 см от низа колонны (царга 2 метра) температуры 78.2 - срабатывает СТОП.
Чего пока нет, но пишется:
Автоматом после разгона переходить на работу на себя, понижая мощность.
После работы на себя, автоматом отбирать головы
С помощью гидравлического автостопа и датчика уровня голов в банке, автоматически переходить в режим отбора тела.
Ждать пока длительность СТОП не будет больше 8 минут и завершать процесс.

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

asvar Специалист Крога 163 30
Отв.609  25 Нояб. 13, 21:06
Дописали тут совместными усилиями код, боль мень привели в порядок. По замыслу - полный автомат (для моей колонны). На выходных будет проверка боем. Кроме всего что описывал, еще добавилась возможность изменения основных параметров из меню настройки, перед запуском процесса. И приделал еще тумблер для переключения режимов управления колонной (ручной режим и авторежим) - переключать можно в любое время работы колонны.
После обкатки выложу код и распиновку подключения к ардуине всех обвесов.
msg31 Научный сотрудник Барнаул 4.6K 2.5K
Отв.610  27 Нояб. 13, 18:32
Программа "Термометр винокура". По заданной температуре, умноженной на 100 (например 9678 - это 96,78) выдает содержание спирта в объемных частях в формате, умноженном на 10 (например 455 - это 45.5 объемных). Точность проверена по калькулятору Руди и в худшем случае составляет +-0.2 объемных, самая большая погрешность после температуры 99 - до 0.5 объемных (это сделано специально по причине экономии памяти на Atmega16). Написана на С, но может быть легко переведена на ардуиновский язык.


eeprom unsigned char tempr[47]={80,10,10,15,110,100,85,85,80,80,75,70,60,50,30,80,50,20,70,40,20,70,30,30,45,55,40,30,50,70,72,48,60,30,45,45,40,25,15,20,30,25,35,10,20,10,5};
eeprom unsigned char spirt[47]={99,11,11,11,108, 88,70,41,45,37,31,25,22,19,17,15,14,11,11,10,10,16, 8, 7,13,11, 9, 9,11,11,11,10,10, 6,12,11,11, 8, 9,10,11, 8,18, 4,10,11,9};

int GetSpirt(unsigned int T)
{
   
   int T1=7815;
   int S1=972;              
   char n=46;
   if (T<T1) return -1;
   while (n>=0)
   {                  
       if (T<T1+tempr[n])
       {
           //Нашли промежуток для интерполящии
           S1 = S1 - (T-T1)*spirt[n] / tempr[n];
           return S1;
       }
       T1=T1+tempr[n];
       S1=S1-spirt[n];
       n--;
   }
   return 0;

}
Bitner Научный сотрудник NN 950 416
Отв.611  27 Нояб. 13, 20:45
Библиотека для создания Меню на дисплеях
hxxp://forum.amperka.ru/threads/%D0%91%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D0%9C%D0%B5%D0%BD%D1%8E-%D0%BD%D0%B0-%D0%B4%D0%B8%D1%81%D0%BF%D0%BB%D0%B5%D1%8F%D1%85.1815/

ММХО погонял в протеусе, понравилось.
asvar Специалист Крога 163 30
Отв.612  28 Нояб. 13, 00:41
Программа "Термометр винокура". По заданной температуре, умноженной на 100 (например 9678 - это 96,78) выдает содержание спирта в объемных частях в формате, умноженном на 10 (например 455 - это 45.5 объемных). Точность проверена по калькулятору Руди и в худшем случае составляет +-0.2 объемных, самая большая погрешность после температуры 99 - до 0.5 объемных (это сделано специально по причине экономии памяти на Atmega16). Написана на С, но может быть легко переведена на ардуиновский язык.
msg31, 27 Нояб. 13, 18:32
Это получится типа того что игорь223 начал продавать у себя на сайте?
http://samogon-i-vodka.ru/...2129/item_7653/
msg31 Научный сотрудник Барнаул 4.6K 2.5K
Отв.613  28 Нояб. 13, 04:05
Это получится типа того что игорь223 начал продавать у себя на сайте?
http://samogon-i-vodka.ru/...2129/item_7653/
asvar, 28 Нояб. 13, 00:41
Ну да, принцип тот же.
mihase Специалист Краснодар 165 74
Отв.614  01 Дек. 13, 03:08
ММХО погонял в протеусе, понравилось.
Bitner, 27 Нояб. 13, 20:45
Может кто тут на дуинке тестил? Бьюсь на Меге 2560 - ошибки вылазят, использую библиотеку LiquidCrystal_I2C для 20х4, может в этом проблема, скетч написан для стандартной LiquidCrystal...
lakmus Специалист С-Петербург 196 49
Отв.615  02 Дек. 13, 01:49
Может кто тут на дуинке тестил? Бьюсь на Меге 2560 - ошибки вылазят, использую библиотеку LiquidCrystal_I2C для 20х4, может в этом проблема, скетч написан для стандартной LiquidCrystal...
mihase, 01 Дек. 13, 03:08
попробуй i2c адрес 0x27
SDA и SCL к +5V подтянул через 10к?
контрастность крутил?

а по хорошему - надо сначала запустить его на примере для LiquidCrystal_I2C
mihase Специалист Краснодар 165 74
Отв.616  02 Дек. 13, 03:59
попробуй i2c адрес 0x27
lakmus, 02 Дек. 13, 01:49
Дык так то экран работает прекрасно, только адрес у меня 0х3F, а я вот менюху выше указанную не могу загрузить, проверку делаю, куча ошибок..
lakmus Специалист С-Петербург 196 49
Отв.617  02 Дек. 13, 07:19
Дык так то экран работает прекрасно, только адрес у меня 0х3F, а я вот менюху выше указанную не могу загрузить, проверку делаю, куча ошибок..
mihase, 02 Дек. 13, 03:59
кроме очевидной замены в проекте на LiquidCrystal_I2C и его инициализац.
надо поменять все вхождения LiquidCrystal в библиотечных (MyMenu) файлах  на LiquidCrystal_I2C

mihase Специалист Краснодар 165 74
Отв.618  03 Дек. 13, 01:41
надо поменять все вхождения LiquidCrystallakmus, 02 Дек. 13, 07:19
Согласен. А, пожалуйста, тыкни пальцем, куда смотреть, и как это провернуть?
lakmus Специалист С-Петербург 196 49
Отв.619  03 Дек. 13, 02:31, через 51 мин
вот  уже измененные библиотеки MyMenu: так наверн. проще!

зы: добавил файл проекта для и2с (MyMenuAmperkaI2C)
в ардуинной оболочке пашет...
[size=2pt]а из под NetBeans - увы ,[/size]