Добро пожаловать,
Гость
|
Железо для умного дома
ТЕМА: Прошивка NRF24le1
Прошивка NRF24le1 25 Июль 2017 15:58 #19309
|
прокатит отключение подтяжки у ds18b20.
Батарею можно мерять через ацп вроде, только не помню там используется ли опорное напряжение или нет.. |
Основной канал проекта в Telegram t.me/wifi_iot
Администратор запретил публиковать записи гостям.
Спасибо сказали: loginkr
|
Прошивка NRF24le1 28 Июль 2017 01:24 #19337
|
Пытаюсь реализовать контроль питания для dht22.
Собственно вопрос, что делаю не так ? Спящий режим не работает. Код не работает до тех пор , пока не отсоединю датчик #define chclient 2 // номер клиента 1...
#define SPEED 1 // 1 - 250кб , 2 - 1 мб , 3 -2 мб.
#define PAlevel 3 // мощность 0..3
#define CHANNEL 75 // 123
#define Crclength false //
#define AutoAck 2 // 0 - crc off ,1 - 8bit ,2 - 16bit
#define VBAT ADC_CHANNEL_AIN3 // P0.3 - VBAT
#define DHTPIN GPIO_PIN_ID_P0_4
#define DHTPOWER_PIN GPIO_PIN_ID_P0_6
#define timeout 30 //sec
#include "../libs.h"
#include "../nRFLE.c"
typedef struct{
unsigned char identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ
int Analog;
long count;// счетчик передач для контроля качества канала
int temperature_Sensor; //передаём температуру.
int Humidity_Sensor;// передаём влажность
}
nf1;
nf1 clientnf;
unsigned char datadht[5];
//==========DHT11/22==============
uint8_t dhtread ()
{
unsigned char j = 0, i = 0;
datadht[0] = datadht[1] = datadht[2] = datadht[3] = datadht[4] = 0;
//pin as output and set 0
gpio_pin_configure(DHTPIN, GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT);
delay_ms(18);
gpio_pin_val_set(DHTPIN); //set 1
//pin as input
gpio_pin_configure(DHTPIN,GPIO_PIN_CONFIG_OPTION_DIR_INPUT);
//=============check DHT response
delay_us(51);
if (gpio_pin_val_read(DHTPIN)) return 0;
delay_us(81);
if (!gpio_pin_val_read(DHTPIN)) return 0;
//===============receive 40 data bits
while (gpio_pin_val_read(DHTPIN));
for (j=0; j<5; j++)
{
datadht[j]=0;
for(i=0; i<8; i++)
{
while (!gpio_pin_val_read(DHTPIN));
delay_us (30);
if (gpio_pin_val_read(DHTPIN))
datadht[j]|=1<<(7-i);
while (gpio_pin_val_read(DHTPIN));
}
}
return 1;
}
//====================main========================
void main()
{
unsigned int crcdata;
CLKLFCTRL = 1;
gpio_pin_configure(DHTPOWER_PIN, // укажем необходимые параметры
GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT |
GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR |
GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH);
gpio_pin_val_clear(DHTPIN);
gpio_pin_configure(DHTPIN, GPIO_PIN_CONFIG_OPTION_DIR_INPUT);
rtc2_configure(RTC2_CONFIG_OPTION_COMPARE_MODE_0_RESET_AT_IRQ ,32767*timeout); //65535=2 сек, 32767=1 сек
rtc2_run();
pwr_clk_mgmt_wakeup_configure(PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_ALWAYS,0);
//pwr_clk_mgmt_wakeup_configure(PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_NEVER,0);
//pwr_clk_mgmt_wakeup_configure(PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_IF_INT_ENABLED,0);
//interrupt_control_rtc2_enable();
sti();
adc_configure (ADC_CONFIG_OPTION_RESOLUTION_10_BITS|ADC_CONFIG_OPTION_REF_SELECT_VDD |ADC_CONFIG_OPTION_RESULT_JUSTIFICATION_RIGHT);
radiobegin(); //
openAllPipe(); // открываем прием/передачу
setChannel(CHANNEL);
setDataRate(SPEED);
setAutoAck(Crclength);
setCRCLength(AutoAck);
setPALevel(PAlevel);
clientnf.identifier=chclient;
while(1) {
gpio_pin_val_set(DHTPOWER_PIN);
delay_ms(250);
dhtread ();
gpio_pin_val_clear(DHTPOWER_PIN);
crcdata= (datadht[0] + datadht[1] + datadht[2] + datadht[3]);
if (datadht[0]==0 && datadht[1]==0 && datadht[2]==0 && datadht[3]==0) {
clientnf.temperature_Sensor=0;
clientnf.Humidity_Sensor=0;
//обработка ошибки:не подключен датчик !!
} else
if ( crcdata == datadht[4]) {
if (datadht[1]==0 && datadht[3]==0) {
// dht11
clientnf.temperature_Sensor=datadht[2]*10; // умножение на 10,чтобы было однинаково как у dht22,можно убрать.
clientnf.Humidity_Sensor=datadht[0]*10;
}else {
// dht22
clientnf.Humidity_Sensor = (datadht[0] * 256 + datadht[1]);
clientnf.temperature_Sensor = ((datadht[2] & 0x7F)* 256 + datadht[3]);
if (datadht[2] & 0x80) clientnf.temperature_Sensor *= -1;
}
} else {/* обработка ошибки:ошибка CRC */}
adc_power_up();
clientnf.Analog=adc_start_single_conversion_get_value(VBAT);
rf_power_up(1);
rf_write_tx_payload((const uint8_t*)&clientnf, 32, true); //transmit received char over RF
//wait until the packet has been sent or the maximum number of retries has been reached
while(!(rf_irq_pin_active() && rf_irq_tx_ds_active()));
if (clientnf.count <= 2147483646) clientnf.count++; /// счетчик передач для контроля качества канала
else clientnf.count = 0;
rf_irq_clear_all(); //clear all interrupts in the 24L01
adc_power_down();
rf_power_down();
//pwr_clk_mgmt_enter_pwr_mode_memory_ret_tmr_on(); // 1mkA
//pwr_clk_mgmt_enter_pwr_mode_deep_sleep(); // 0mkA
//pwr_clk_mgmt_enter_pwr_mode_standby(); // 1500 mkA
pwr_clk_mgmt_enter_pwr_mode_register_ret(); // 450 mkA
}
} |
Администратор запретил публиковать записи гостям.
|
Прошивка NRF24le1 16 Авг 2017 19:32 #19457
|
Спящий режим с контролем питания для dht22 почти готов. Требовалось добавить резистор на 250-350 Ом на питание датчика и паузу после подачи питания на него.
Проблема в следующем счетчик передач не считает - всегда показывает 0 и интервал сна не соответствует введенному. Подскажите где косяк. Спасибо #define chclient 2 // номер клиента 1...
#define SPEED 1 // 1 - 250кб , 2 - 1 мб , 3 -2 мб.
#define PAlevel 3 // мощность 0..3
#define CHANNEL 75 // 123
#define Crclength false //
#define AutoAck 2 // 0 - crc off ,1 - 8bit ,2 - 16bit
#define VBAT ADC_CHANNEL_AIN3 // P0.3 - VBAT
#define DHTPIN GPIO_PIN_ID_P0_4
#define DHTPOWER_PIN GPIO_PIN_ID_P0_6
#define timeout 32767 * 10 //sec
#include "../libs.h"
#include "../nRFLE.c"
typedef struct{
unsigned char identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ
int Analog;
long count;// счетчик передач для контроля качества канала
int temperature_Sensor; //передаём температуру.
int Humidity_Sensor;// передаём влажность
}
nf1;
nf1 clientnf;
//============================= disconnect GPIO ==================
void disconnectGPIO()
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
P0CON = 0x70 | i;
P1CON = 0x70 | i;
P2CON = 0x70 | i;
P3CON = 0x70 | i;
}
}
//===================
unsigned char datadht[5];
//==========DHT11/22==============
uint8_t dhtread ()
{
unsigned char j = 0, i = 0;
datadht[0] = datadht[1] = datadht[2] = datadht[3] = datadht[4] = 0;
//pin as output and set 0
gpio_pin_configure(DHTPIN, GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT);
delay_ms(18);
gpio_pin_val_set(DHTPIN); //set 1
//pin as input
gpio_pin_configure(DHTPIN,GPIO_PIN_CONFIG_OPTION_DIR_INPUT);
//=============check DHT response
delay_us(51);
if (gpio_pin_val_read(DHTPIN)) return 0;
delay_us(81);
if (!gpio_pin_val_read(DHTPIN)) return 0;
//===============receive 40 data bits
while (gpio_pin_val_read(DHTPIN));
for (j=0; j<5; j++)
{
datadht[j]=0;
for(i=0; i<8; i++)
{
while (!gpio_pin_val_read(DHTPIN));
delay_us (30);
if (gpio_pin_val_read(DHTPIN))
datadht[j]|=1<<(7-i);
while (gpio_pin_val_read(DHTPIN));
}
}
return 1;
}
//====================main========================
void main()
{
//long __xdata countloop;
__xdata __at(0x0100) long countloop; //counter for loop
unsigned int crcdata;
countloop = 0;
disconnectGPIO();
gpio_pin_configure(DHTPOWER_PIN, // укажем необходимые параметры
GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT |
GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR |
GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH);
gpio_pin_val_clear(DHTPIN);
gpio_pin_configure(DHTPIN, GPIO_PIN_CONFIG_OPTION_DIR_INPUT);
CLKLFCTRL = 1;
rtc2_configure(RTC2_CONFIG_OPTION_COMPARE_MODE_0_RESET_AT_IRQ , timeout); //65535=2 сек, 32767=1 сек
rtc2_run();
pwr_clk_mgmt_wakeup_configure(PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_ALWAYS,0);
sti();
adc_configure (ADC_CONFIG_OPTION_RESOLUTION_10_BITS|ADC_CONFIG_OPTION_REF_SELECT_VDD |ADC_CONFIG_OPTION_RESULT_JUSTIFICATION_RIGHT);
radiobegin(); //
openAllPipe(); // открываем прием/передачу
setChannel(CHANNEL);
setDataRate(SPEED);
setAutoAck(Crclength);
setCRCLength(AutoAck);
setPALevel(PAlevel);
clientnf.identifier=chclient;
while(1) {
gpio_pin_val_set(DHTPOWER_PIN);
delay_ms(800);
dhtread ();
gpio_pin_val_clear(DHTPOWER_PIN);
crcdata= (datadht[0] + datadht[1] + datadht[2] + datadht[3]);
if (datadht[0]==0 && datadht[1]==0 && datadht[2]==0 && datadht[3]==0) {
clientnf.temperature_Sensor=0;
clientnf.Humidity_Sensor=0;
//обработка ошибки:не подключен датчик !!
} else
if ( crcdata == datadht[4]) {
if (datadht[1]==0 && datadht[3]==0) {
// dht11
clientnf.temperature_Sensor=datadht[2]*10; // умножение на 10,чтобы было однинаково как у dht22,можно убрать.
clientnf.Humidity_Sensor=datadht[0]*10;
}else {
// dht22
clientnf.Humidity_Sensor = (datadht[0] * 256 + datadht[1]);
clientnf.temperature_Sensor = ((datadht[2] & 0x7F)* 256 + datadht[3]);
if (datadht[2] & 0x80) clientnf.temperature_Sensor *= -1;
}
} else {/* обработка ошибки:ошибка CRC */}
adc_power_up();
clientnf.Analog = adc_start_single_conversion_get_value(VBAT);
clientnf.count = countloop;
rf_power_up(1);
rf_write_tx_payload((const uint8_t*)&clientnf, 32, true); //transmit received char over RF
//wait until the packet has been sent or the maximum number of retries has been reached
while(!(rf_irq_pin_active() && rf_irq_tx_ds_active()));
if (countloop <= 2147483646) countloop++; /// счетчик передач для контроля качества канала
else countloop = 0;
rf_irq_clear_all(); //clear all interrupts in the 24L01
//adc_power_down();
//rf_power_down();
pwr_clk_mgmt_enter_pwr_mode_memory_ret_tmr_on(); // 1mkA
//pwr_clk_mgmt_enter_pwr_mode_deep_sleep(); // 0mkA
//pwr_clk_mgmt_enter_pwr_mode_standby(); // 1500 mkA
//pwr_clk_mgmt_enter_pwr_mode_register_ret(); // 450 mkA
}
} |
Администратор запретил публиковать записи гостям.
|
Прошивка NRF24le1 16 Авг 2017 21:31 #19458
|
Здравствуйте.
1. Таймаут не соответствует указанному (32768*10) потому, что Вы пытаетесь положить в двухбайтную переменную число больше 65535. Таймаут rtc не может быть более двух секунд. Организуйте цикл с отдельным счетчиком, например, и засыпайте нужное количество раз на 2 секунды. 2. Счетчик передач не считает потому, что Вы его инициализируете в 0 в начале функции main(). При просыпании из memory retention программа начинает исполняться с самого начала (аналог ресета), и счетчик сбрасывается. Или используйте register retention, или не илициализируйте счетчик. Еще в даташите указано, что при использовании memory retention нужно закрывать "защелку", а при возвращении из сна - открывать (смотри описание регистра OPMCON). loginkr пишет: Спящий режим с контролем питания для dht22 почти готов. Требовалось добавить резистор на 250-350 Ом на питание датчика и паузу после подачи питания на него. Проблема в следующем счетчик передач не считает - всегда показывает 0 и интервал сна не соответствует введенному. Подскажите где косяк. Спасибо |
Администратор запретил публиковать записи гостям.
Спасибо сказали: loginkr
|
Прошивка NRF24le1 17 Авг 2017 15:22 #19464
|
Здравствуйте.
Сильно интересует наиболее "правильная" и экономичная в плане энергопотребления реализация режима memory retention. Если я правильно понял даташит, есть ровно два пути, которые позволят проснуться без внешних воздействий и съесть минимум энергии во сне. Оба они - это memory retention with timers on, разница только в способе выхода из сна. Вариант 1. Просыпаться по прерыванию от RTC. Минусы - максимальное время сна 2 секунды, и нужно организовывать цикл со счетчиком, если нужно спать дольше. Соответственно, кушает энергию при просыпаниях. Плюсы - сохраняется содержимое DataRetentive SRAM, значения переменных в ней сохраняются между циклами сна. Вариант 2. Просыпаться по Watchdog. Плюсы - время сна до 512 секунд. Минусы - watchdog жестко сбрасывает контроллер и периферию, соответственно значения переменных между циклами не сохраняются. Хотелось бы узнать мнение гуру, как "правильно" и наиболее экономно реализовать интервалы сна порядка минут. Возможно, есть еще варианты? Я сейчас реализовал вариант 1 (ради сохранения значений переменных между циклами). Еще есть некоторые непонятки с радиомодулем. Непонятка 1. В даташите (стр. 20) написано, что при входе в memory retention значения регистров радиомодуля теряются. Но, при выводе значений регистров видно, что они не сбрасываются. Так надо ли заново конфигурировать радиомодуль при выходе из сна? Непонятка 2. После отправки данных с включенным AutoAck при недоступности приемника имею вечное зависание на конструкции while(!(rf_irq_pin_active() && rf_irq_tx_ds_active())); while((!((tmp&0xF)&&rf_irq_max_rt_active()))&&(!(rf_irq_pin_active() && rf_irq_tx_ds_active()))); Заранее спасибо за комментарии. |
Последнее редактирование: 17 Авг 2017 15:31 от fixxxer.
Администратор запретил публиковать записи гостям.
|
Прошивка NRF24le1 17 Авг 2017 15:25 #19465
|
Спасибо за подсказки.
Тоже сделал по 1 варианту #define chclient 2 // номер клиента 1...
#define SPEED 1 // 1 - 250кб , 2 - 1 мб , 3 -2 мб.
#define PAlevel 3 // мощность 0..3
#define CHANNEL 75 // 123
#define Crclength false //
#define AutoAck 2 // 0 - crc off ,1 - 8bit ,2 - 16bit
#define DHTPIN GPIO_PIN_ID_P0_4
#define DHTPOWER_PIN GPIO_PIN_ID_P0_6
#define timeout 5 //sec * 2
#include "../libs.h"
#include "../nRFLE.c"
typedef struct{
unsigned char identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ
int temperature_Sensor; //передаём температуру.
int Humidity_Sensor;// передаём влажность
}
nf1;
nf1 clientnf;
//__xdata __at(0x0100) long countloop; //counter for loop
__xdata __at(0x0100) int sleep_counter;
//__xdata __at(0x0500) int first_boot;
//============================= disconnect GPIO ==================
void disconnectGPIO()
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
P0CON = 0x70 | i;
P1CON = 0x70 | i;
P2CON = 0x70 | i;
P3CON = 0x70 | i;
}
}
//===================
unsigned char datadht[5];
//==========DHT11/22==============
uint8_t dhtread ()
{
unsigned char j = 0, i = 0;
datadht[0] = datadht[1] = datadht[2] = datadht[3] = datadht[4] = 0;
//pin as output and set 0
gpio_pin_configure(DHTPIN, GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT);
delay_ms(18);
gpio_pin_val_set(DHTPIN); //set 1
//pin as input
gpio_pin_configure(DHTPIN,GPIO_PIN_CONFIG_OPTION_DIR_INPUT);
//=============check DHT response
delay_us(51);
if (gpio_pin_val_read(DHTPIN)) return 0;
delay_us(81);
if (!gpio_pin_val_read(DHTPIN)) return 0;
//===============receive 40 data bits
while (gpio_pin_val_read(DHTPIN));
for (j=0; j<5; j++)
{
datadht[j]=0;
for(i=0; i<8; i++)
{
while (!gpio_pin_val_read(DHTPIN));
delay_us (30);
if (gpio_pin_val_read(DHTPIN))
datadht[j]|=1<<(7-i);
while (gpio_pin_val_read(DHTPIN));
}
}
return 1;
}
//====================main========================
void main()
{
//long __xdata
unsigned int crcdata;
// Open latch
OPMCON = 0x00;
//countloop = 0;
disconnectGPIO();
gpio_pin_configure(DHTPOWER_PIN, // укажем необходимые параметры
GPIO_PIN_CONFIG_OPTION_DIR_OUTPUT |
GPIO_PIN_CONFIG_OPTION_OUTPUT_VAL_CLEAR |
GPIO_PIN_CONFIG_OPTION_PIN_MODE_OUTPUT_BUFFER_NORMAL_DRIVE_STRENGTH);
gpio_pin_val_clear(DHTPIN);
gpio_pin_configure(DHTPIN, GPIO_PIN_CONFIG_OPTION_DIR_INPUT);
CLKLFCTRL = 1;
rtc2_configure(RTC2_CONFIG_OPTION_COMPARE_MODE_0_RESET_AT_IRQ ,65535); //65535=2 сек, 32767=1 сек
rtc2_run();
pwr_clk_mgmt_wakeup_configure(PWR_CLK_MGMT_WAKEUP_CONFIG_OPTION_WAKEUP_ON_RTC2_TICK_ALWAYS,0);
sti();
radiobegin(); //
openAllPipe(); // открываем прием/передачу
setChannel(CHANNEL);
setDataRate(SPEED);
setAutoAck(Crclength);
setCRCLength(AutoAck);
setPALevel(PAlevel);
clientnf.identifier=chclient;
while(1) {
if(sleep_counter>=timeout){
gpio_pin_val_set(DHTPOWER_PIN);
delay_ms(800);
dhtread ();
gpio_pin_val_clear(DHTPOWER_PIN);
crcdata= (datadht[0] + datadht[1] + datadht[2] + datadht[3]);
if (datadht[0]==0 && datadht[1]==0 && datadht[2]==0 && datadht[3]==0) {
clientnf.temperature_Sensor=0;
clientnf.Humidity_Sensor=0;
//обработка ошибки:не подключен датчик !!
} else
if ( crcdata == datadht[4]) {
if (datadht[1]==0 && datadht[3]==0) {
// dht11
clientnf.temperature_Sensor=datadht[2]*10; // умножение на 10,чтобы было однинаково как у dht22,можно убрать.
clientnf.Humidity_Sensor=datadht[0]*10;
}else {
// dht22
clientnf.Humidity_Sensor = (datadht[0] * 256 + datadht[1]);
clientnf.temperature_Sensor = ((datadht[2] & 0x7F)* 256 + datadht[3]);
if (datadht[2] & 0x80) clientnf.temperature_Sensor *= -1;
}
} else {/* обработка ошибки:ошибка CRC */}
adc_power_up();
rf_power_up(1);
rf_write_tx_payload((const uint8_t*)&clientnf, 32, true); //transmit received char over RF
//wait until the packet has been sent or the maximum number of retries has been reached
while(!(rf_irq_pin_active() && rf_irq_tx_ds_active()));
sleep_counter=0;
}else{
if(sleep_counter<0){
sleep_counter = 0;
}else{
sleep_counter++;
}
}
disconnectGPIO();
rf_irq_clear_all(); //clear all interrupts in the 24L01
//adc_power_down();
//rf_power_down();
// Lock latch
OPMCON |= 0x02;
pwr_clk_mgmt_enter_pwr_mode_memory_ret_tmr_on(); // 1mkA
//pwr_clk_mgmt_enter_pwr_mode_deep_sleep(); // 0mkA
//pwr_clk_mgmt_enter_pwr_mode_standby(); // 1500 mkA
//pwr_clk_mgmt_enter_pwr_mode_register_ret(); // 450 mkA
}
} Все же интересно как тогда в конструкторе работает и счетчик и memory retention. Можете поделиться кодом ? |
Администратор запретил публиковать записи гостям.
|
Модераторы: FlyRouter
Время создания страницы: 0.120 секунд