-
ipua
-
-
Не в сети
-
Давно я тут
-
- Сообщений: 89
- Спасибо получено: 8
-
Репутация: 1
-
|
Есть дачик Oregon. Хочу его даные передать на ЕСП. Скетч сделал с homes-smart.ru/index.php/oborudovanie/be...k-vlazhnosti-arduino и стандартного декодера Орегон.
По отдельности обе части работают. А вместе ведут себя странно - RF24 хаб ничего не принимает. Но если сначала залить сканер каналов (из библиотеки NRF), а потом этот скетч, то все работает, но до первой перезагрузки.
Не могу найти в чем причина...
Вот этот скетч
//NRF24l01+ connected to 9,10,11,12,13
#define chclient 3 // номер клиента 1...
#define timeoutper 400 // таймаут запросов от сервера.
#define timesend 20000 // интервал отправки данных,для обычных датчиков можно установить время выше.
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
unsigned long time1 = 0;
unsigned long time2 = 0;
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10
RF24 radio(9, 10);
// 0 -прием , 1 -передача
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL};
// структура принятых данных.МЕНЯТЬ НЕЛЬЗЯ
typedef struct {
byte identifier;
byte val1;
byte val2;
byte val3;
byte val4;
}
nf0;
nf0 servernf;
// структура отправляемых данных.Изменяемые данные.Размер структуры должен быть не больше 32 байт !
typedef struct {
byte identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ
int temperature_Sensor;// передаём температуру.
int Humidity_Sensor;// передаём влажность
// boolean test_data;
int Analog;
int Analog1;
unsigned int Error_Message; // счетчик ошибок
unsigned long count;// счетчик передач для контроля качества канал
}
nf1;
nf1 clientnf;
#define PORT 2
class DecodeOOK {
protected:
byte total_bits, bits, flip, state, pos, data[25];
virtual char decode (word width) =0;
public:
enum { UNKNOWN, T0, T1, T2, T3, OK, DONE };
DecodeOOK () { resetDecoder(); }
bool nextPulse (word width) {
if (state != DONE)
switch (decode(width)) {
case -1: resetDecoder(); break;
case 1: done(); break;
}
return isDone();
}
bool isDone () const { return state == DONE; }
const byte* getData (byte& count) const {
count = pos;
return data;
}
void resetDecoder () {
total_bits = bits = pos = flip = 0;
state = UNKNOWN;
}
// add one bit to the packet data buffer
virtual void gotBit (char value) {
total_bits++;
byte *ptr = data + pos;
*ptr = (*ptr >> 1) | (value << 7);
if (++bits >= 8) {
bits = 0;
if (++pos >= sizeof data) {
resetDecoder();
return;
}
}
state = OK;
}
// store a bit using Manchester encoding
void manchester (char value) {
flip ^= value; // manchester code, long pulse flips the bit
gotBit(flip);
}
// move bits to the front so that all the bits are aligned to the end
void alignTail (byte max =0) {
// align bits
if (bits != 0) {
data[pos] >>= 8 - bits;
for (byte i = 0; i < pos; ++i)
data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits));
bits = 0;
}
// optionally shift bytes down if there are too many of 'em
if (max > 0 && pos > max) {
byte n = pos - max;
pos = max;
for (byte i = 0; i < pos; ++i)
data[i] = data[i+n];
}
}
void reverseBits () {
for (byte i = 0; i < pos; ++i) {
byte b = data[i];
for (byte j = 0; j < 8; ++j) {
data[i] = (data[i] << 1) | (b & 1);
b >>= 1;
}
}
}
void reverseNibbles () {
for (byte i = 0; i < pos; ++i)
data[i] = (data[i] << 4) | (data[i] >> 4);
}
void done () {
while (bits)
gotBit(0); // padding
state = DONE;
}
};
// 433 MHz decoders
class OregonDecoderV2 : public DecodeOOK
{
public:
OregonDecoderV2() {}
// add one bit to the packet data buffer
virtual void gotBit (char value)
{
if(!(total_bits & 0x01))
{
data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
}
total_bits++;
pos = total_bits >> 4;
if (pos >= sizeof data)
{
resetDecoder();
return;
}
state = OK;
}
virtual char decode(word width)
{
if (200 <= width && width < 1200)
{
byte w = width >= 700;
switch (state)
{
case UNKNOWN:
if (w != 0)
{
// Long pulse
++flip;
}
else if (w == 0 && 24 <= flip)
{
// Short pulse, start bit
flip = 0;
state = T0;
}
else
{
// Reset decoder
return -1;
}
break;
case OK:
if (w == 0)
{
// Short pulse
state = T0;
}
else
{
// Long pulse
manchester(1);
}
break;
case T0:
if (w == 0)
{
// Second short pulse
manchester(0);
}
else
{
// Reset decoder
return -1;
}
break;
}
}
else if (width >= 2500 && pos >= 8)
{
return 1;
}
else
{
return -1;
}
return 0;
}
};
OregonDecoderV2 orscV2;
volatile word pulse;
void ext_int_1(void) {
static word last;
// determine the pulse length in microseconds, for either polarity
pulse = micros() - last;
last += pulse;
}
// Oregon packet decoder
float temperature(const byte* data)
{
int sign = (data[6]&0x8) ? -1 : 1;
float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0);
return sign * temp;
}
byte humidity(const byte* data)
{
return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4) ;
}
float humi_ext(const byte* data)
{
return humidity(data) + ((data[7]&0xF0)>>4)/10.0 ;
}
byte battery(const byte* data)
{
return (data[4] & 0xF) ;
}
byte serial(const byte* data)
{
return (data[3]);
}
byte channel(const byte* data)
{
byte channel;
switch (data[2]>>4)
{
case 0x1:
channel = 1;
break;
case 0x2:
channel = 2;
break;
case 0x4:
channel = 3;
break;
}
return channel;
}
int Sum(byte count, const byte* data)
{
int s = 0;
for(byte i = 0; i<count;i++)
{
s += (data[i]&0xF0) >> 4;
s += (data[i]&0xF);
}
if(int(count) != count)
s += (data[count]&0xF0) >> 4;
return s;
}
void reportSerial (const char* s, class DecodeOOK& decoder) {
byte pos;
const byte* data = decoder.getData(pos);
Serial.print(millis()/1000.,3);
Serial.print(" ");
Serial.print(s);
Serial.print(' ');
for (byte i = 0; i < pos; ++i) {
Serial.print(data[i] >> 4, HEX);
Serial.print(data[i] & 0x0F, HEX);
}
if( data[8] == (Sum(8,data)-0xa)&0xFF ){
Serial.print(" "+String(channel(data))+" "+String(serial(data),HEX));
Serial.print(" "+String(temperature(data),1)+" "+String(humidity(data))+"%");
Serial.print(" "+String(battery(data)));
// report t and h to NRF
clientnf.temperature_Sensor = temperature(data) * 10;
clientnf.Humidity_Sensor = humidity(data) * 10;
clientnf.Analog = channel(data);
clientnf.Analog1 = battery(data);
} else {
int sum = ((Sum(6, data) + (data[6]&0xF) - 0xa) & 0xff);
if( (sum&0xF) == (data[6]>>4) && (sum>>4) == (data[7]&0xF) ){
Serial.print(" "+String(channel(data))+" "+String(serial(data),HEX));
Serial.print(" "+String(temperature(data),1));
Serial.print(" "+String(battery(data)));
} else {
Serial.print(" Checksum error");
}
}
Serial.println();
decoder.resetDecoder();
}
void setup () {
Serial.begin(115200);
Serial.println("\n[ookDecoder]");
pinMode(PORT, INPUT); // use the AIO pin
digitalWrite(PORT, 1);
attachInterrupt(digitalPinToInterrupt(PORT), ext_int_1, CHANGE);
radio.begin();
// выбор скорости
// radio.setDataRate(RF24_250KBPS);
radio.setDataRate(RF24_1MBPS);
// radio.setDataRate(RF24_2MBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setChannel(100); //тут установка канала
radio.setCRCLength(RF24_CRC_16);
// radio.setAutoAck(false); // выключить аппаратное потверждение
radio.setRetries(15, 15);
radio.openWritingPipe(pipes[1]); // Открываем канал передачи
// radio.openReadingPipe(1, pipes[0]); // Открываем канал приема
clientnf.identifier = chclient;
}
byte errorstate;
void loop () {
static int i = 0;
cli();
word p = pulse;
pulse = 0;
sei();
// if (p != 0){ Serial.print(++i); Serial.print('\n');}
if (p != 0) {
if (orscV2.nextPulse(p))
reportSerial("OSV2", orscV2);
// запоминаем даные
// if (orscV3.nextPulse(p))
// reportSerial("OSV3", orscV3);
}
if ((millis() - time2) >= timesend || errorstate != 0) {
if (clientnf.count <= 2147483646) clientnf.count++; // счетчик передач для контроля качества канала
else clientnf.count = 0;
radio.stopListening();
// clientnf.Analog = analogRead(0); //пример передачи int данных
bool ok = radio.write( &clientnf, sizeof(clientnf) );
Serial.print(clientnf.count);
Serial.println(" transmitted");
// radio.startListening();
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > timeoutper ) timeout = true;
if ( timeout ) {
// счетчик ошибок
clientnf.Error_Message++;
errorstate++; // счетчик ошибок для повтора
}
else {
radio.read( &servernf, sizeof(servernf) );
errorstate = 0;
}
if (errorstate >= 3) errorstate = 0; // не более 3 попыток для повтора
//************************************************************************************************/
// if (servernf.identifier == chclient) { // выполнение команд с сервера,если данные предназначены для этого клиента:
// val1= 10 -значит дергаем пинами, val2 - номер пина, val3 - состояние пина
// не забудте установить режим OUTPUT для нужных пинов.
// nRF-USB write 1 10 7 1 1 - что значит установить на 7 выводе логический уровень 1
// if (servernf.val1 == 10) digitalWrite(servernf.val2, servernf.val3);
// val1= 11 -значит управляем ШИМ пинами, val2 - номер пина, val3 - уровень 0..255.
// не забудте установить режим OUTPUT для нужных пинов.
// ШИМ возможен только на некоторых пинах !!
// if (servernf.val1 == 11) analogWrite(servernf.val2, servernf.val3);
// }
time2 = millis();
}
}
Прошу помощи...
|