gate nrf24l01+enc28j60
- Войдите на сайт для отправки комментариев
Пт, 06/02/2015 - 13:07
Добрый день.
Делаю шлюз на данных модулях. Возникли проблемы. Устройство работает через раз, не выполняется php скрипт на сервере. Контроллер собран на Atmega328 c бутлоадером optiboot. Питание на всех мродулях 3.3в 3А, на разьёмах модулей стоят электролиты. Устройство пингутся, отвечает на запрос ?help (значит enc в работе), при поступлении данных по радиоканалу в Serial выводятся соответствующие данные (значит nrf тоже в работе), а скрипт не выполняется :( Если отключить питание, а затем его включить то всё может работать, а может и нет. Незнаю куда копать :(
Вот код
#include "EtherCard.h"
#include <string.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//-----------------------------------------------------------------------------------
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,1,99 }; // adress of gate
static byte gwip[] = { 192,168,1,20 };
static byte hisip[] = { 192,168,1,163 }; // adress server
byte Ethernet::buffer[700];
static BufferFiller bfill;
const char PROGMEM webserver[] = "192.168.1.163";
RF24 radio(9,8);
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
typedef struct{
int NUM;
int VCC;
float TEMP;
float OTHER;
}
B_t;
B_t data;
//---------------------ответ серверу--------------------------------------
void send_http_ok()
{
bfill = ether.tcpOffset();
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
ether.httpServerReply(bfill.position());
}
//--------------------смотрим ответ от appache ---------------------------------------
static void my_callback (byte status, word off, word len) {// всё можно закоментировать
Ethernet::buffer[off+300] = 0;
Serial.print((const char*) Ethernet::buffer + off);
}
//-----------------------------------------------------------
void setup () {
Serial.begin(9600);
Serial.println("Start");
ether.begin(sizeof Ethernet::buffer, mymac,7 );
ether.staticSetup(myip, gwip);
ether.copyIp(ether.hisip, hisip);
radio.begin();
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
radio.startListening();
}
//-----------------------------------------------------------
void ethernet()
{
word pos = ether.packetLoop(ether.packetReceive());
if(pos)
{
parse_str(pos); // parsing comand
send_http_ok(); // отсылаем стандартный http request !!обязательно
}
}
//-----------------------------------------------------------
void radioch()
{
if ( radio.available() ) // если пришли данные по радио
{
radio.read( &data, sizeof(data) );
char buffer[250];
char conv_buffer[11];
buffer[0] = 0;
strcat_P(buffer, PSTR("n1="));
strcat(buffer, itoa(data.NUM, conv_buffer, 10));
strcat_P(buffer, PSTR("&n2="));
strcat(buffer, dtostrf(data.VCC, 2, 0, conv_buffer));
strcat_P(buffer, PSTR("&n3="));
strcat(buffer, dtostrf(data.TEMP, 2, 2, conv_buffer));
strcat_P(buffer, PSTR("&n4="));
strcat(buffer, dtostrf(data.OTHER, 2, 2, conv_buffer));
Serial.println(buffer);
ether.browseUrl(PSTR("/gate.php?"), buffer, webserver, my_callback);
delay(10);
}
}
//-----------------------------------------------------------
void loop ()
{
ethernet();
radioch();
}
//---------------------обработки web запросов---------------------------------------
void parse_str(char pos)
{
if(strstr((char *)Ethernet::buffer + pos, "GET /?help") != 0)
{
help();
}
if(strstr((char *)Ethernet::buffer + pos, "GET /?status") != 0)
{
send_status();
}
}
//-----------------------------------------------------------------------------------
void send_status()
{
Serial.print("status...");
bfill = ether.tcpOffset();
// bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n" // $S - значение float $D - значение int
// "name=street<BR>vcc=$D<BR>temp=$S<P>name=room<BR>vcc=$D<BR>temp=$S"),
// obj[1].vcc, dtostrf(obj[1].temp,3,2,tempS), obj[2].vcc, dtostrf(obj[2].temp,3,2,tempS));
ether.httpServerReply(bfill.position());
}
//-----------------------------------------------------------------------------------
void help()
{
Serial.print("Help...");
bfill = ether.tcpOffset();
bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n""<p>Last command</p>"));
ether.httpServerReply(bfill.position());
}
Заметил одну особенность, на работу скрипта влияет пауза в 81 строке и размер буфера в 68 строке.
Что может быть?
Неужели никто не знает?
В таких приложениях где используются относительно большие массивы данных и много текстовых строк часто все упирается в перерасход оперативной памяти. Контроля за этим в ардуине нет
проделайте оптимизацию с тем чтобы сократить как размер скетча так и размер используемов памяти, причем важны именно пики использования как например в функции radioch. Кстати вы там собираете большую строку, ее можно собрать одним вызовом функции sprintf_P, без использования массива для промежуточной конвертации на 11 байт. Но надо посмотреть сократит или увеличит это размер скетча, функция sprintf прожерлива, но остальные функции конвертации тоже прожерливы, вопрос кто кого
И еще. Можете сделать отключаемым использование Serial, или временно закоментировать или используя условную компиляцию (#define #if). И посмотрите что будет. Отключение Serisl высвободит довольно приличный кусок флэша и рама
axill, спасибо за совет. при использовании sprintf вообще отказывалось работать, serial убирал но ничего не изменилось. так и не установил от чего зависит работа девайса в целом
можно проверить сколько памяти осталось например этим
https://github.com/maniacbug/MemoryFree
или так
http://microsin.net/programming/AVR/arduino-determining-amount-free-and-...
при использовании sprintf строка запроса верно формировалась? sprintf не самая простая в применении функция, много ньюансов
sprintf(queryString, "n1=%d&n2=%d&n3=%0d.%d&n4=%0d.%d" "\r\n", num, vcc, (int)data.TEMP, abs(d1), (int)data.OTHER, abs(d2)); ether.browseUrl(PSTR("/gate.php?"), queryString, webserver, my_callback);результат формирования проверял через
Serial.println(queryString);но это ничего не дало :(
freeMemory()=763
Вроде норм
только вставь в разных местах лупа. может на каком то куске кода память заканчивается
все норм, стоит как вкопаный (783)
И опять все перестало работать :(
Перепробовал всё, менял паузы и размер буферов, всё так же. Может железо глючит?
Собрал железо на макетке, залил скетч, опять через раз работает. С меня пиво тому, кто поможет!!