Не работает часть кода для ENC28J60

xorkrus
Offline
Зарегистрирован: 22.09.2013

Здравия желаю, уважаемые. Имею такой проблемный код:


#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&deg;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&#37;</td>",humidity);
  add_string(mystr, plen);
  sprintf(mystr,"<td>Temperature<br/>%d&deg;C</td></tr>",temp_dht);
  add_string(mystr, plen);
  MS_DHT11();
  sprintf(mystr,"<tr><td>Humidity<br/>%d&#37;</td>",humidity2);
  add_string(mystr, plen);
  sprintf(mystr,"<td>Temperature<br/>%d&deg;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%, ибо раньше он стоял просто в лупе и все было хорошо.

Подскажите пожалуйста, в чем проблема?

toly
Offline
Зарегистрирован: 17.05.2014

Возможно какая-то из библиотек использует тот же таймер, который нужен для millis()

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Начните с того что вы не понимаете как это работает на самом деле.

Где тот код который постоянно проверяет есть ли что в буфере ENC28j60?

Может там пинг пришол или запрос? вот этот код должен быть в loop и его работа должна быть без всяких таймерв, как и обработка

uint16_t plen, dat_p; // глобальные
dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
if(dat_p != 0) eth_upd();

Во вторых библиотека эта слишком толстая - у вас памяти точно хватает?

 

xorkrus
Offline
Зарегистрирован: 22.09.2013

Ну честно говоря в этот кусок особо не вникал вообще. Поставил в лупе эти строки - заработало всё, спасибо!

Я вообще больше в железе, а в коде только костыли умею :)

xorkrus
Offline
Зарегистрирован: 22.09.2013

Забыл спросить: а почему нельзя этот код по таймеру?

xorkrus
Offline
Зарегистрирован: 22.09.2013

Добавлю сюда же вопрос, дабы не плодить.

В строке 73 хотел сделать давление с десятичной точкой и двумя циферами после, простым float pressure_mf = pressure_pa/133.3

На LCD это выводится как 745.09, а в 73 строку (и в 156 тоже), выводится некое пятизначное число (во время теста оно было от 17100 до 22150). Попытался перевести из int32_t в char (нагуглил), но в ответ все равно идет пятизначное число вместо давления. Что я опять делаю не так? :)

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013
dtostrf((float)pressure_pa/133.3, 6, 2, mystr);

В avr_libc - функция sprintf - не может обрабатывать float

xorkrus
Offline
Зарегистрирован: 22.09.2013

С таким кодом происходит сбой в виде "Соединение было сброшенно". Если на экран - ардеинка перезагружается

То мой косяк был %)

Нету сбоя, но вместо 748 получаем 2022