• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Модуль 8266-12е + ili9163c(9341)

Thorn

New member
Добрый день форумчане. Решил расширить возможности обычной Nano с её 32кб памяти и гоняю node MCU для акваконтроллера. Всё удобно но портов маловато, аналоговый так вообще один нуда вопрос дургой. При работе с библой Dallasa для ds18b20 #include <DallasTemperature.h> БЕЗ старта tft показания температур выводятся прекрасно. Но стоит в setup прописать TFT_ILI9163C(cs,dc).begin(); то само собой дисплейчик работать начинает и показывает все параметры с dht, bmp180 - вобщем со всего кроме далласа - по нему сразу показания -127 вываливаются в serial и собственнов монитор и веб- страничку. Повторюсь только с ds18b20 такая беда.
Выручайте тотже код (почти) сами понимаете за рядом изменения что на mega xn она nano работает.
 

Thorn

New member
Покурил ветку про I2c - пригодится, только у меня обычная шина oneWire для ds18b20 + и spi для tft экранчиков :(
Вобщем понимаю что знаний 1% у меня счас но придётся видимо все получать с датчиков на Nano а управлять реле и передавать в сеть 8266-12e по sofwareSerial к примеру. Жаль платка мосчная, памяти просто некуда девать, а столько граблей у меня повылазило.
 

NeoroN

Member
Гонял ILI9341 через прошивку на LUA( www.nodemcu-build.com ) вместе с далласом - норм работает - даллас висел на GPIO5. Так что проблема вряд ли аппаратная. Проверяйте ваш кривой код и кривые библиотеки. Вообще чтобы проги на C++ работали нужно много знаний.
 

Thorn

New member
Ну я не то что бы совсем новичок но довольно сложные проекты собирал НО всё на Mega\nano\mini. Код кривой - ну как сказать если он работает везде а в 8266 нет - явно я что то упускаю, только что. И к примеру кусок кода для работы с определённой адресацией по ds18b20 везде работает а здесь нет, что только непробовал. Имеется ввиду работа без библы самого далласа а лишь oneWire.
Раз вы вязлись критиковать - помочь прошу разъяснить почему с onodeMcu - не работает следующее? строчек минимум - просто по однопроводной схеме я получаю несколько температур по адресам - не боясь что напутаю и прочее. Везде работает а с 8266 нет, как так. Спасибо
Код:
#include <OneWire.h>                 //Подключаем библиотеку для температурного датчика DS18B20

//=====Termo_Sensor*
int tempPin=12;                     //Определяем порт шины OneWire (IC) для температурного датчика DS18B20                              
OneWire ds(tempPin);                //Создаем объект для работы с термометром
byte flagDallas=0;                  //Флаг для обработки показаний с датчиков Dallas
byte data[12];
byte addr1[8]={0x28, 0x33, 0x4B, 0xEA, 0x05, 0x00, 0x00, 0x54};     //адрес датчика DS18B20_в парничке
byte addr2[8]={0x28, 0xFF, 0xB5, 0x24, 0x54, 0x14, 0x01, 0xC7};     //адрес датчика DS18B20_на улице
byte addr3[8]={0x28, 0xF2, 0x29, 0xEB, 0x05, 0x00, 0x00, 0xE1};     //адрес датчика DS18B20_грунт :)
unsigned int raw;                   //Если экранированный кабель, можно подключать до 32 термо-датчиков DS18B20
float temp[3];                      //Температура в парничке \ на уличке \ грунта

unsigned long prvMlsTemp=0;         //Предыдущее показание обновления температур
unsigned long tzad=millis();        //Переменная задержки (пока для ds18b20, ds.write)

unsigned long zadM[4];              //Массив для задержек меню
const long zadTime[]={100,500,750,1000,2000,3000,5000,10000,60000};

void setup() {
  Serial.begin(9600);                                //Инициализация Serial-порта
}

//=========== Считывание температур
void dallas(){
  ds.reset();
  ds.write(0xCC);                                      //Команда инициации 
  ds.write(0x44);                                      //Start conversion, with parasite power on at the end
    tzad=millis()+750; flagDallas=1;}
  float DS18B20(byte *adres){
  ds.reset();
  ds.select(adres);
  ds.write(0xBE);                                      //Read Scratchpad
    for (byte i=0; i<9; i++) data[i]=ds.read();        //We need 9 bytes
    int raw=(data[1]<<8) | data[0];                    //Переводим в температуру  
    float celsius=(float)raw/16.0;                     //Для ds18b20 делим на "16", для ds18s20 на "2"
    return celsius;
}

void loop(){
      if (millis()-prvMlsTemp>zadTime[6]&&flagDallas!=1){dallas();
      Serial.println(temp[0],1);Serial.println(temp[1],1);Serial.println(temp[2],1);}
}
 

bmk74

New member
Ну я не то что бы совсем новичок но довольно сложные проекты собирал НО всё на Mega\nano\mini. Код кривой - ну как сказать если он работает везде а в 8266 нет - явно я что то упускаю, только что. И к примеру кусок кода для работы с определённой адресацией по ds18b20 везде работает а здесь нет, что только непробовал. Имеется ввиду работа без библы самого далласа а лишь oneWire.
Раз вы вязлись критиковать - помочь прошу разъяснить почему с onodeMcu - не работает следующее? строчек минимум - просто по однопроводной схеме я получаю несколько температур по адресам - не боясь что напутаю и прочее. Везде работает а с 8266 нет, как так. Спасибо
Код:
#include <OneWire.h>                 //Подключаем библиотеку для температурного датчика DS18B20

//=====Termo_Sensor*
int tempPin=12;                     //Определяем порт шины OneWire (IC) для температурного датчика DS18B20                           
OneWire ds(tempPin);                //Создаем объект для работы с термометром
byte flagDallas=0;                  //Флаг для обработки показаний с датчиков Dallas
byte data[12];
byte addr1[8]={0x28, 0x33, 0x4B, 0xEA, 0x05, 0x00, 0x00, 0x54};     //адрес датчика DS18B20_в парничке
byte addr2[8]={0x28, 0xFF, 0xB5, 0x24, 0x54, 0x14, 0x01, 0xC7};     //адрес датчика DS18B20_на улице
byte addr3[8]={0x28, 0xF2, 0x29, 0xEB, 0x05, 0x00, 0x00, 0xE1};     //адрес датчика DS18B20_грунт :)
unsigned int raw;                   //Если экранированный кабель, можно подключать до 32 термо-датчиков DS18B20
float temp[3];                      //Температура в парничке \ на уличке \ грунта

unsigned long prvMlsTemp=0;         //Предыдущее показание обновления температур
unsigned long tzad=millis();        //Переменная задержки (пока для ds18b20, ds.write)

unsigned long zadM[4];              //Массив для задержек меню
const long zadTime[]={100,500,750,1000,2000,3000,5000,10000,60000};

void setup() {
  Serial.begin(9600);                                //Инициализация Serial-порта
}

//=========== Считывание температур

void loop(){
      if (millis()-prvMlsTemp>zadTime[6]&&flagDallas!=1){dallas();
      Serial.println(temp[0],1);Serial.println(temp[1],1);Serial.println(temp[2],1);}
}

Код:
void dallas(){
  ds.reset();
  ds.write(0xCC);                                      //Команда инициации
   ds.write(0x44);                                      //Start conversion, with parasite power on at the end
    tzad=millis()+750;
    flagDallas=1;
}
float DS18B20(byte *adres){
  ds.reset();
  ds.select(adres);
  ds.write(0xBE);                                      //Read Scratchpad
    for (byte i=0; i<9; i++)
           data[i]=ds.read();        //We need 9 bytes
    int raw=(data[1]<<8) | data[0];                    //Переводим в температуру
    float celsius=(float)raw/16.0;                     //Для ds18b20 делим на "16", для ds18s20 на "2"
    return celsius;
}
Я так понимаю это все таки две функции... а в лупе я нашел у вас только одну...первую, Откуда вы вообще температуру то получаете...а вообще код конечно мощный... благо памяти на данных девайсах хоть отбавляй.:)

так пример оптимизации функция dallas здесь избыточна по определению все в одну можно запихнуть
Код:
#define MAXTIME 3000 // время через которое произойдет повторный запрос измерения
#define MINTIME 50 //время нужное для измерения
float temp[3];

int32 lastTime;
enum typeM
{
     Measurm = 0,
     GetTemp
};

float DS18B20(typeM type byte *adres){
  int raw = 0;
  int currtime;
  if(type == Measurm )
  {
         ds.reset();
         ds.write(0xCC);                                      //Команда инициации
         ds.write(0x44);                                      //Start conversion, with parasite power on at the end
         lastTime=millis();
         return 0x0;
   }
  currtime = mills()-lastTime;
  if(type == GetTemp && currtime > MINTIME && currtime<MAXTIME )
  {
      ds.reset();
      ds.select(adres);
      ds.write(0xBE);                                      //Read Scratchpad
      for (byte i=0; i<2; i++) // зачем считать все девять если вам нужно только первые два значения CRC  вы все равно не проверяете
        raw |= data[1]<<(i*8);                    //Тупо Записываем сразу, нафиг лишнее
//           data[i]=ds.read();        //We need 9 bytes
     flagDallas = 0;
     return =(float)raw/16.0;                     //Для ds18b20 делим на "16", для ds18s20 на "2"
    //return celsius;
   }
   if( currtime >= MAXTIME )
   {
         DS18B20(Measurm, NULL);
   }
   return 0x0;
}
И в цикле уже опрашивать датчики
Код:
temp[0] =DS18B20(GetTemp, addr1);
Ну и так 3 раза, Писал на коленке могут быть опечатки..но смысл такой и еще желательно запись в temp делать в функции сразу все три значения...ну это как нибудь без меня перепишите
 
Последнее редактирование:

rst

Member
Ну я не то что бы совсем новичок
Ну да -по коду это заметно :D

byte addr1[8]={0x28, 0x33, 0x4B, 0xEA, 0x05, 0x00, 0x00, 0x54}; //адрес датчика DS18B20_в парничке
byte addr2[8]={0x28, 0xFF, 0xB5, 0x24, 0x54, 0x14, 0x01, 0xC7}; //адрес датчика DS18B20_на улице
byte addr3[8]={0x28, 0xF2, 0x29, 0xEB, 0x05, 0x00, 0x00, 0xE1}; //адрес датчика DS18B20_грунт :)
Не многовато-ли 24 байта ОЗУ + 24 байта флеша всего на 3 адреса?

for (byte i=0; i<9; i++) data=ds.read();

В нормальном коде пишут:
#define ncell(m) (sizeof(m) / sizeof((m)[0]))
for (byte i=0; i<ncell(data); i++) data=ds.read();
int raw=(data[1]<<8) | data[0]; //Переводим в температуру
8-битное значение сдвинем на 8 бит, что будет? Правильно ==0. Может компилятор конечно перед операцией и сделает приведение к int, а может и нет.
Опять-же: byte - знаковый тип или беззнаковый? В первом случае будут сюрпризы :D
Да и в случае беззнакового: DS18B20 вроде знаковое значение возвращает? Тогда опять косяк.
А вообще делается так (если DS18B20 возвращает беззнаковое):
int raw = *(u16 *)&data[0];
или так (если DS18B20 возвращает беззнаковое):
int raw = *(s16 *)&data[0];
О значении типов u16 и s16 догадайтесь сами.
float celsius=(float)raw/16.0; //Для ds18b20 делим на "16", для ds18s20 на "2"
float понадобился только для деления на 16??? И это на 8-битном дохлом МК, с наверняка ещё и дохлым кол-вом флеша...
Вот это и называется: "г****код" :eek:
 

Thorn

New member
Спасибо громадное за разъяснения и потраченное на меня время :). Много из того что увидел и понять пока не могу, все предыдущие коды писал по букварику так было проще. Век живи - век учись а всё равно дураком помрёш. О результатах отпишусь - чегоу меня получилось.
 
Сверху Снизу