Jump to content
iT4iT.CLUB

Neon

Members
  • Content Count

    18
  • Joined

  • Last visited

Community Reputation

4 Neutral
  1. приветствую а не подскажете, хотя бы направление , какие шаги нужно выполнить, чтобы можно добавить в метеостанцию работу с nrf24? как понял нужно добавить обработчик сюда void loop() { /* Обработчики */ wifi.handleEvents(); http.handleClient(); cron.handleEvents(); }
  2. передатчик потребляет в режиме сна около 3 мкА, при передаче данных раз в минуту довольно долго должен проработать
  3. в теме про метеостанцию писал про датчик с передатчиком на NRF24L01 и возможность использования с метеостанцией простой код приемника на esp // https://aterlux.ru/article/nrf24l01p #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line, для 20x4 - 0x3F //#include <SPI.h> //#include "nRF24L01.h" #include "RF24.h" int32_t data[5]; RF24 radio(99, 15); // CE, CSN, 99 - это заглушка, чтобы освободить один пин, если передача не предполлагается то можно CE просто подтянуть резистором к питанию, иначе нужно указать вывод void setup(void) { lcd.init(); lcd.backlight(); radio.begin(); radio.setAutoAck(true); // radio.setAutoAck(true); включение и ли отклучение автоподтверждения radio.setChannel(100); radio.setDataRate (RF24_2MBPS); // скорость обмена RF24_2MBPS, RF24_1MBPS, RF24_250KBPS - максимальная чувствительность на 250 кбитс, NRF24L01 без плюса 250 не умеет radio.setPALevel (RF24_PA_MAX); // уровень мощности RF24_PA_MIN -18dBm, RF24_PA_LOW -12dBm, RF24_PA_HIGH -6dBM, RF24_PA_MAX 0dBm radio.openReadingPipe(1, 0xAABBCCDD11LL); radio.startListening(); } void loop(void) { if(radio.available()){ // Если в буфере имеются принятые данные, то получаем номер трубы, по которой они пришли, по ссылке на переменную pipe radio.read( &data, sizeof(data)); } // Читаем данные в массив data и указываем сколько байт читать lcd.setCursor(0,0); lcd.print("Temp "); lcd.print(float(data[3])/100, 2); lcd.print(" "); lcd.print((char)223); lcd.print("C"); lcd.setCursor(0,1); lcd.print("Battery "); lcd.print(float(data[0])/1000,3); lcd.print(" v"); lcd.setCursor(0,2); // на некоторых 4 строчных дисплеях в 3 и 4 строке ноль сдвинут на 4 символа вправо, поэтому нулевой символ это -4 lcd.print("Packet N "); lcd.print(data[1]); delay (100); } код передатчика // тема на форуме - http://forum.ixbt.com/topic.cgi?id=48:12460&r=lYjQSTixmu#2 // библиотека для датчика BME280 - https://github.com/sergeyastakhov/BME280 (чтобы не было конфликтов с другими библиотеками, желательно ее разместить в папке скетча) // потребление всего модуля в power save - 2.0 мкА(из них NRF24 - 0.9 мкА), 1.1 мкА - atmega168 // обязательно параллельно батарейке доп емкость около 2200мкф 6.3 в - падение при передаче 10 мВ, ток утечки конденсатора после подформовки менее 100 нА, - http://forum.ixbt.com/topic.cgi?id=48:11468:3073#3073 // измерение напряжение батарейки с помощью измерения питания atmega // еще можно питать атмегу напрямую от лития и измерять ее напряжение, а NRF и BME280 питается от стабилизатора 3.3 вольта с маленькой утечкой, например mcp1700-3302, ток утечки около 1.5 мкА // I2C преобразователь уровней не нужен, главное чтобы подтягивающие резисторы I2C питались от 3.3 вольт // проблема с вотчдогом - http://arduino.ru/forum/apparatnye-voprosy/ne-mogu-vylechit-vatchdog-na-goloi-atmege328r-s-vnutr-taktirovaniem-8-mgts #include <avr/wdt.h> #include <avr/sleep.h> //#include <avr/power.h> #include "RF24.h" RF24 radio(9, 10); // CE_PIN, CSN_PIN byte count = 0; // счетчик количества просыпаний int32_t data[5]; // на данный момент используется int32_t чтобы иметь возможность получить большие числа счетчика передач, для тестирования продолжительности работы от батарейки, // потом можно обычный int // data 0 - данные АЦП или пересчитанное напряжение питания c тремя знаками(в милливольтах, на стороне приемника переменная float деленная на 1000 // data 1 - счетчик отправленных пакетов, сбрасывается при снятии питания // data 2 - P атмсомферное в мм, можно умножить на 10 если нужны десятые, тогда на стороне приемника делить на 10 и float // data 3 - Т температура умноженное на 100 на стороне приемника float делить на 100 // data 4 - H влажность умноженная на 100 #include "BME280.h" // при таком написании компилятор ищет библиотеку в первую очередь в папке скетча using namespace BME280; class CustomI2CProtocol : public I2CProtocol { public: virtual void init() { I2CProtocol::init(); Wire.setClock(400000); // частота работы I2C, 400 кГц - максимум для BME280, уже чувствительна к качеству и длине линии } // реальная частота I2C зависит от регистра и строки в wire.cpp - TWBR = ((F_CPU / frequency) - 16) / 2 и при частоте 8 МГц она ниже, около 250 кГц // https://www.avrfreaks.net/forum/twi-clock-divider?name=PNphpBB2&file=viewtopic&t=79562 }; BME280Sensor bme280 = BME280Sensor(new CustomI2CProtocol()); //BME280Sensor bme280 = BME280Sensor(new I2CProtocol()) - I2C работает на частоте по умолчанию - 100 кГц ISR (TIMER2_OVF_vect) { // из прерывания по таймеру 2 нельзя выходить слишком быстро, поэтому инкрементирование переменной расположим здесь count++; } void setup() { MCUSR = 0; // необходимо при использовании вотчдога для сброса контроллера при зависании на выпонении кода wdt_disable(); // иначе при первом сбросе вотчдогом, будет установлено минимальное время вотчдога 0.15 с, и мк зависнет на этом цикле PORTC |= (1 << PC1); // включение светодиода, для индикации запуска мк delay(10); DDRB = 0b11000001; // настраиваем неиспользуемые выводы(и порты) на выход DDRC = 0b11111111; DDRD = 0b11111111; //clock_prescale_set(clock_div_2); // деление тактовой частоты для получения 4 МГц для работы atmega168 вплоть до 1.8 вольта bme280.init(false); bme280.setHumidityMode(Over_1); // установка режима измерения влажности, остальные при запуске измерения //bme280.setMode(Forced, Over_1, Over_1, Over_1); // Forced - однократный режим измрения, все оверсемплинги(T, P, Hum) = 1 PRR = (1<<PRTIM1) | (1<<PRUSART0); // отключаем неиспользуемую периферию, (1<<PRTIM2) - работает в асинхронном режиме // (1<<PRTIM0) - так не работает передача, видимо count использует этот таймер // (1<<PRSPI), (1<<PRTWI)- не отключаем, SPI - для NRF24 и TWI(по другому I2C) - для BME280 radio.begin(); radio.setAutoAck(true); // подтверждение приема, true - включено, false - отключено radio.setRetries (2, 1); // количество попыток передачи если включен режим автоподтверждения приема, первая цифра - задержка между передачами, 1 = 250 мкс, вторая - количество попыток передачи radio.setChannel(100); // номер канала, можно перед выбором просканировать эфир чтобы выяснить менее зашумленные каналы(использовать скетч scanner из библ. RF24) radio.setDataRate (RF24_2MBPS); // скорость обмена RF24_2MBPS, RF24_1MBPS, RF24_250KBPS - максимальная чувствительность на 250 кбитс radio.setPALevel (RF24_PA_MAX); // уровень мощности RF24_PA_MIN -18dBm, RF24_PA_LOW -12dBm, RF24_PA_HIGH -6dBM, RF24_PA_MAX 0dBm radio.openWritingPipe (0xAABBCCDD11LL); // уникальный номер передатчика, на приемнике должен быть такой же ADCSRA = 0; // отключаем АЦП ACSR |= (1<<ACD); // отключаем компаратор ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // настраиваем АЦП на измерение собственного напряжения питания, опорное 1.1 вольт DIDR0 = 1; // отключаем цифровой вход выводов АЦП, он тоже немного потребляет ASSR |= (1<<AS2); // Асинхронный режим TCCR2A = (0<<WGM21)|(0<<WGM20); //режим normal TCCR2B = (1<<CS22)|(1<<CS21)|(1<<CS20); // clk/1024 TCNT2 = 0x00; // начальное значение таймера // OCR2A = 0x00; OCR2B = 0x00; TIMSK2 |= (1 << TOIE2); // разрешаем прерывание по переполнению Т2 SMCR = _BV(SM1) | _BV(SM0); // Power_Save, set_sleep_mode(SLEEP_MODE_PWR_SAVE), set_sleep_mode (SLEEP_MODE_PWR_DOWN) - выбор режима сна radio.powerDown(); PORTC &= ~_BV(PC1); // выключение светодиода } void loop() { if ( count >= 8 ) { // передавая один раз в 64 секунды = 8 radio_(); TCNT2 = 0x00; } while(ASSR&(1<<TCN2UB)){;} //wait to TCNT update!!! TCNT2 = 0x00; sleep_enable(); //SMCR |= _BV(SE); sleep_cpu (); } void radio_() { wdt_enable(WDTO_1S); radio.powerUp(); data[1]++; ADCSRA |= _BV(ADEN); // включаем АЦП Measurement measurement = bme280.readMeasurement(); // опрос датчика и расчет параметров data[2] = (measurement.getPressure32()*1000/133322); data[3] = (measurement.getTemperature()*100); data[4] = (measurement.getHumidity()*100); bme280.setMode(Forced, Over_1, Over_1); // запуск однократного измерения и установка оверсемплингов T, P, без влажности //bme280.setMode(Forced, Over_1, Over_1, Over_1); // запуск однократного измерения и установка оверсемплингов T, P, Hum ADCSRA |= _BV(ADSC); // запуск конверсии while (bit_is_set(ADCSRA,ADSC)); // измерение uint8_t low = ADCL; // сначала читаем ADCL - это расблокирует чтение ADCH uint8_t high = ADCH; int volt = (high<<8) | low; // данные АЦП data[0] = (1135494/volt); // 1135494 подобрано эксперементально и в общем случае равно 1100 милливольт опорное * 1024, но опорное не всегда 1100 мВ ADCSRA = 0; // отключаем АЦП // ******************************************** // код до этого места примерно 1700 мкс, убираем в файле RF24.cpp задержку delay(5) и добавляем перед отправкой данных // задержку в 2.3 мс, чтобы в сумме задежка получилась 4 мс, это минимальная задержка от команды powerUp() до write() // при которой стабильно работает большой модуль на RF24, smd модуль работает и при меньшей задержки, т.к. разные кварцы clock_prescale_set(clock_div_256); // на время задержки снижаем частоту контроллера до минимально возможной, для снижения энергопотребления delayMicroseconds(10); // на этой частоте для получения 2.3 миллисекунд нужно указать задержку в 256 раз меньше ~ 9 мкс // в этом режиме потребляет только atmega, которая работает на частоте 1/256 от номанальной clock_prescale_set(clock_div_1); // перед отправкой данных снова устанавливаем исходную частоту работы контроллера radio.write(&data, sizeof(data)); radio.powerDown(); count = 0; wdt_disable(); }
  4. стандартно используется 5 проводов, 3 SPI, CE и CSN , если передавать модулем не планируется, а работать только на прием, на CE можно просто подать высокий уровень, итого используется 4 вывода IRQ использовать не обязательно, за раз NRF принимает 32 байта и хранит их в буфере, есть ли в буфере данные проверяется флагом, который после прочтения буфера сбрасывается библиотеку использую RF24, вот так проверяется буфер if(radio.available()){ radio.read( &data, sizeof(data)); } чуть позже выложу простой рабочий скетч на esp, который просто принимает данные
  5. Пробовал подключать nrf24l01+ к esp8266, все работает без проблем Нужно только встроить код работы с nrf в код метеостанции и передать данные переменным метеостанции
  6. заливал, но все равно не грузилось вэб содержимое, заработало только когда указал что флеш 4 мб, но попробую еще возможно ли не очень сложным способом добавить к метеостанции работу с NRF24L01+, чтобы радиомодуль принимал данные показаний датчиков и передавал их метеостанции интересует куда вставить код работы с NRF24 и как передать данные коду метеостанции, скетч работы с NRF24 в принципе есть, возможно нужно будет немного доработать
  7. установил 8 мб, скетчи работают, а вот метеостанцию запустить не удалось, похоже какая то проблема с SPIFFS так как светодиод моргает, в монитор инфу пишет, точку доступа создает, к ней подключаюсь и все, в браузере ничего
  8. разобрался с RSSI, оказывается смотрел ее не подключившись к роутеру, то есть не настроив имя и пароль для подключения к роутеру...
  9. сейчас посмотрел разметку в файле eagle.flash.4m3m.ld и возможно понял почему RSSI, вроде бя я стирал не только скетч но и всю память ESP, а там похоже хранятся какие то настройки... по разметке получается для скетча всегда оставляется 1 мегабайт, остальное под SPIFFS или вообще пусто
  10. код вроде на месте, сам кружок RSSI есть , но показывает 0, а шкала круга на максимуме причем для проверки скачал архив с форума , раскомментировал RSSI и все равно 0, возможно что-то настройками IDE намудрил, буду пробовать проверять перепайка была в первую очередь интересна чтобы запустить станцию на ESP01, ESP01 и датчик BME280 получается метеостанция очень небольшого небольшого размера, но довольно функциональная если памяти будет больше, то можно в вэб интерфейс выводить больше различной информации, даже видеоролик какой нибудь можно вывести или фото , хотя это наверное актуально для яesp32 например вид города, фотографию сложно прикрутить? или сделать типа скринсейвера, чтобы фото менялись, главное чтобы сильно браузер не нагружало
  11. Обратил внимание , что в Ардуино IDE при в плате esp можно выбрать 8 и 16 мегабайт
  12. А у esp32 есть какие то функции отсутствующие в esp8266? У меня почему-то исчез вывод показаний RSSI, это произошло после нескольких перепрошивок esp, теперь при прошивке даже разных esp все равно не выводит... поэтому то и скачивал заново прошивку, думал может я что-то изменил и не заметил Кстати, запустил метеостанцию на esp01 :) Поставил на нее 4 МБ и датчик BME280
  13. Kitsum здравствуйте, вы похоже недавно корректировали файлы и забыли в файле webserver.h в строке String codeTranslate(int code) { return ESP8266WebServer::_responseCodeToString(code); } подчеркивание перед responseCodeToString(code);
  14. красиво, но похоже ресурсоемко, у меня в брауезере притормаживает...
  15. верно , смысла особого возится с памятью более 4 Мб нет, наверное это больше имеет смысл в esp1, там обычно 1 Мб, если нужна компактность и не нужно много GPIO мне esp07 пришла тоже с 1 Мб, брал ее так как у нее есть разьем для антенны
×
×
  • Create New...