Не работает часть кода для ENC28J60
- Войдите на сайт для отправки комментариев
Чт, 31/07/2014 - 20:15
Здравия желаю, уважаемые. Имею такой проблемный код:
#include <SPI.h> // Need for ENC28J50 #include <Wire.h> // Common library #include "DHT.h" // DHT11 & DHT22 Library #include "af_BMP085.h" // Simple library for BMP085 #include <EtherShield.h> // ENC28J60 Library #include <LiquidCrystal_I2C.h> // Display with PFC8574 #include "Timer.h" // http://github.com/JChristensen/Timer // BMP085: SDA->A4 / SCL->A5 // DHT11: DATA->A0 // DHT22: DATA->A1 // JACK: DATA->D4 // DISPLAY-I2C: SDA->A4 SCL->A5 BACKLIGHT->D3 // ENC28J60: SCK->D13 MOSI->D12 MISO->D11 INT->D2 RST->RST CS->D10 // ISP: SCK->D13 MOSI->D12 MISO->D11 RST->RST // DIODE GREEN: +->D8 // DIODE ORANGE: +->D7 // BUZZER: SIGNAL->D9 // Setting vars #define BACKLIGHT_PIN 3 // Display backlight with npn-transistor #define DHT_S1_PIN A1 // DHT22 / AM2302 #define DHT_S2_PIN A0 // DHT11 #define D_ORANGE_PIN 7 // Diode orange #define D_GREEN_PIN 8 // Diode green #define BUZZER_PIN 9 // Buzzer #define WIND_PIN 4 // Anemometer #define MYWWWPORT 80 // Web-server port #define BUFFER_SIZE 500 // Size of TCP buffer LiquidCrystal_I2C lcd(0x20,4,5,6,0,1,2,3,7, NEGATIVE); Timer t; //instantiate the timer object int di = 0; // display update dht dht_s1, dht_s2; Adafruit_BMP085 bmp; static uint8_t mymac[6] = {0x54,0x55,0x55,0x10,0x00,0x25}; static uint8_t myip[4] = {192,168,1,88}; static byte dnsip[] = {8,8,8,8}; static uint8_t buf[BUFFER_SIZE+1]; int humidity = 0, temp_dht = 0, humidity2 = 0, temp_dht2 = 0, temp_bmp = 0, temp = 0; int32_t pressure_pa = 0, pressure_mm = 0; EtherShield es=EtherShield(); // loop counter int count = 0; uint8_t temp_cel[8] = {B00110,B01001,B01001,B00110,B00000,B00000,B00000}; //градус // 200 OK HTTP uint16_t http200ok(void) { return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"))); } // add to string in output http data int add_string(char* str, uint16_t &plen) { int i = 0; while (str[i]) { buf[TCP_CHECKSUM_L_P + 3 + plen] = str[i]; i++; plen++; } } // main webpage uint16_t print_webpage(uint8_t *buf) { uint16_t plen; plen=http200ok(); plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<head><title>Metro Weather</title></head><body><center><table border=2>")); char mystr[220]; MS_BMP085(); sprintf(mystr,"<tr><td>Temperature<br/>%d°C</td>",temp_bmp); add_string(mystr, plen); sprintf(mystr,"<td>Pressure<br/>%d mmHg</td></tr>",pressure_mm); add_string(mystr, plen); MS_DHT22(); sprintf(mystr,"<tr><td>Humidity<br/>%d%</td>",humidity); add_string(mystr, plen); sprintf(mystr,"<td>Temperature<br/>%d°C</td></tr>",temp_dht); add_string(mystr, plen); MS_DHT11(); sprintf(mystr,"<tr><td>Humidity<br/>%d%</td>",humidity2); add_string(mystr, plen); sprintf(mystr,"<td>Temperature<br/>%d°C</td></tr>",temp_dht2); add_string(mystr, plen); sprintf(mystr,"</table></center>"); add_string(mystr, plen); return(plen); } void setup(void) { SPI.begin(); es.ES_enc28j60SpiInit(); es.ES_enc28j60Init(mymac); es.ES_init_ip_arp_udp_tcp(mymac,myip, MYWWWPORT); bmp.begin(); lcd.home(); lcd.begin(24,2); lcd.createChar(0, temp_cel); //lcd.setBacklightPin(BACKLIGHT_PIN,NEGATIVE); //lcd.setBacklight(HIGH); pinMode(BACKLIGHT_PIN, INPUT); // set pin to input digitalWrite(BACKLIGHT_PIN, HIGH); // turn on pullup resistors lcd.setCursor(0,0); lcd.print("[Online Meteostation v2]"); lcd.setCursor(0,1); lcd.print("[Build at 32 july 2014 ]"); // ---change 2 delay(3000); lcd.clear(); nm_upd(); DisplayTotal(); // 600000 - 10 min // 60000 - min // 1000 - sec // 100 - millisec // 10 - microsec // 1 sec = 1000ms = 1000000uS int tickEvent1 = t.every(1, eth_upd); // 100 iteration per second - update ethernet catch ---change 1 int tickEvent2 = t.every(600000, nm_upd); // 1 iteration in 10 minute - narodmon.ru update int tickEvent3 = t.every(60000, display_upd); // 1 iteration 1 minute - update display information } void loop(void) { t.update(); } void eth_upd() { char buff[64]; int len = 64; uint16_t plen, dat_p; dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf)); if(dat_p==0){ } else if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>")); goto SENDTCP; } else if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ dat_p=print_webpage(buf); goto SENDTCP; } else if (strncmp("/a ",(char *)&(buf[dat_p+4]),3)==0){ MS_BMP085(); dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("")); char mystr[10]; sprintf(mystr,"%d",temp_bmp); add_string(mystr, dat_p); goto SENDTCP; } else if (strncmp("/b ",(char *)&(buf[dat_p+4]),3)==0){ MS_BMP085(); dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("")); char mystr[10]; sprintf(mystr,"%d",pressure_mm); add_string(mystr, dat_p); goto SENDTCP; } else if (strncmp("/c ",(char *)&(buf[dat_p+4]),3)==0){ MS_DHT22(); dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("")); char mystr[10]; sprintf(mystr,"%d",humidity); add_string(mystr, dat_p); goto SENDTCP; } else if (strncmp("/d ",(char *)&(buf[dat_p+4]),3)==0){ MS_DHT22(); dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("")); char mystr[10]; sprintf(mystr,"%d",temp_dht); add_string(mystr, dat_p); goto SENDTCP; } else if (strncmp("/e ",(char *)&(buf[dat_p+4]),3)==0){ MS_DHT11(); dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("")); char mystr[10]; sprintf(mystr,"%d",humidity2); add_string(mystr, dat_p); goto SENDTCP; } else if (strncmp("/f ",(char *)&(buf[dat_p+4]),3)==0){ MS_DHT11(); dat_p=http200ok(); dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("")); char mystr[10]; sprintf(mystr,"%d",temp_dht2); add_string(mystr, dat_p); goto SENDTCP; } else { dat_p=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>")); goto SENDTCP; } SENDTCP: es.ES_www_server_reply(buf,dat_p); } void nm_upd() { lcd.clear(); lcd.setCursor(0,0); lcd.print("[ Now updating ]"); lcd.setCursor(0,1); lcd.print("[ narodmon.ru ]"); delay(3000); lcd.clear(); display_upd(); } void display_upd() { if (di == 0 || di >= 3) { DisplayTotal(); di = 1; } else if (di == 1) { // Outdoor DisplayOutdoor(); di++; } else if (di == 2) { DisplayIndoor(); di++; } else { di = 0; } } void DisplayTotal() { MS_SensUpdate(); lcd.clear(); lcd.setCursor(0,0); lcd.print("Out: "); lcd.print(temp_dht); lcd.print(" C"); lcd.write(byte(0)); lcd.print(" "); lcd.setCursor(11,0); lcd.print(pressure_mm); lcd.print("p "); lcd.print(humidity); lcd.print("%"); lcd.setCursor(1,1); lcd.print("In: "); lcd.print(temp_dht2); lcd.print(" C"); lcd.write(byte(0)); lcd.print(" "); lcd.print(temp_bmp); lcd.print(" C"); lcd.write(byte(0)); lcd.print(" "); lcd.print(humidity2); lcd.print("%"); } void DisplayIndoor() { MS_DHT11(); MS_BMP085(); lcd.clear(); lcd.setCursor(0,0); lcd.print("Indoor temp: "); lcd.print(temp_dht2); lcd.print(" C"); lcd.write(byte(0)); lcd.print(" "); lcd.print(temp_bmp); lcd.print(" C"); lcd.write(byte(0)); lcd.print(" "); lcd.setCursor(0,1); lcd.print("Indoor humidity: "); lcd.setCursor(17,1); lcd.print(humidity2); lcd.print("% "); lcd.print(pressure_mm); lcd.print("p"); } void DisplayOutdoor() { MS_DHT22(); MS_BMP085(); lcd.clear(); lcd.setCursor(0,0); lcd.print("Outdoor temp: "); lcd.print(temp_dht); lcd.print(" C"); lcd.write(byte(0)); lcd.print(" "); lcd.print(pressure_mm); lcd.print("p"); lcd.setCursor(0,1); lcd.print("Outdoor humidity: "); lcd.setCursor(18,1); lcd.print(humidity); lcd.print("%"); } void MS_SensUpdate() { MS_BMP085(); MS_DHT22(); MS_DHT11(); } // Update only BMP085 void MS_BMP085() { } // Update only DHT22 void MS_DHT22() { } // Update only DHT11 void MS_DHT11() { }
Какой бы я таймер не ставил для eth_upd(), ардуина даже не пингуется, не говоря уже о передаче данных.
То, что код этой процедуры рабочий - 100%, ибо раньше он стоял просто в лупе и все было хорошо.
Подскажите пожалуйста, в чем проблема?
Возможно какая-то из библиотек использует тот же таймер, который нужен для millis()
Начните с того что вы не понимаете как это работает на самом деле.
Где тот код который постоянно проверяет есть ли что в буфере ENC28j60?
Может там пинг пришол или запрос? вот этот код должен быть в loop и его работа должна быть без всяких таймерв, как и обработка
Во вторых библиотека эта слишком толстая - у вас памяти точно хватает?
Ну честно говоря в этот кусок особо не вникал вообще. Поставил в лупе эти строки - заработало всё, спасибо!
Я вообще больше в железе, а в коде только костыли умею :)
Забыл спросить: а почему нельзя этот код по таймеру?
Добавлю сюда же вопрос, дабы не плодить.
В строке 73 хотел сделать давление с десятичной точкой и двумя циферами после, простым float pressure_mf = pressure_pa/133.3
На LCD это выводится как 745.09, а в 73 строку (и в 156 тоже), выводится некое пятизначное число (во время теста оно было от 17100 до 22150). Попытался перевести из int32_t в char (нагуглил), но в ответ все равно идет пятизначное число вместо давления. Что я опять делаю не так? :)
В avr_libc - функция sprintf - не может обрабатывать float
С таким кодом происходит сбой в виде "Соединение было сброшенно". Если на экран - ардеинка перезагружаетсяТо мой косяк был %)
Нету сбоя, но вместо 748 получаем 2022