Arduino, ENC28J60 si MQTT

Categorii: Electronica

06-Sep-2016 17:05 - 581 vizionari

Din greseala mi-am cumparat un adaptor de ethernet bazat pe circuitul ENC28J60.

Cand l-am primit am constatat ca este pentru Arduino, adica este placa shield care se suprapune peste placa Arduino. Eu as fi vrut sa-l folosesc cu PIC-uri Microchip.

Testat pe Arduino Mega 2560, circuitul cu ENC28J60 merge numai ca in imaginea de mai jos,

Shield ENC28J60 cu Arduino Mega 2560

pentru ca Arduino Mega 2560 are pinii SPI (MOSI, MISO, SCK) in alta parte decat Arduino Uno, iar placa ENC28J60 v1.1 este numai pentru Arduino Uno.

Pe placa Arduino Uno, programul functioneaza destul de stabil cu UIPEthernet si MQTT PubSub Client - knolleary.

In documentatia clientului de MQTT este specificat ca nu merge cu ENC28J60, dar autorul bibliotecii UIPEthernet a avut grija sa pastreze compatibilitatea cu biblioteca <Ethernet.h>, care este pentru cipul wiznet (w5200 si w5500). Cipul wiznet este solutia ethernet oficial suportata de Arduino, dar cipul wiznet (shieldul Arduino) este de doua-trei ori mai scump decat solutia cu ENC28J60.

Mi-am cumparat doua module ENC28J60, fara sa fie shield Arduino, la 20 RON bucata:

ENC28J60

Desi ENC28J60 e mai ieftin, interfatarea necesita memorie RAM mai multa (pentru PIC Microchip trebuie cel putin 32k flash si 2-3k ram) si programul este mai complicat.

Shield ENC28J60 cu Arduino Uno

Pentru Arduino, aproape orice program care merge cu biblioteca <Ethernet.h>, trebuie sa mearga fara modificari si cu biblioteca <UIPEthernet.h>.

Programul folosit de mine ocupa 75% din memoria de program a lui Arduino Uno:



#include <avr/wdt.h>

//Aproape orice merge cu
//#include <Ethernet.h>

//trebuie sa mearga si cu
#include <UIPEthernet.h>
#include "PubSubClient.h"



// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 200);  //my ip
IPAddress server(192, 168, 1, 1);

EthernetClient ethClient;
PubSubClient client(ethClient);


unsigned long cnt1, cnt2, cnt3, cnt4;


void watchdogSetup(void)
{
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
/*
WDTCSR configuration:
WDIE = 1: Interrupt Enable
WDE = 1 :Reset Enable
WDP3 = 0 :For 2000ms Time-out
WDP2 = 1 :For 2000ms Time-out
WDP1 = 1 :For 2000ms Time-out
WDP0 = 1 :For 2000ms Time-out
*/
// Enter Watchdog Configuration mode:
WDTCSR |= (1<<WDCE) | (1<<WDE);
// Set Watchdog settings:
WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
sei();
}


void callback(char* topic, byte* payload, unsigned int length) {
  wdt_reset();
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  //Serial.print("Primit:");
  //for (int i=0;i<length;i++)
}


void sendMQTT_Data(){
  int n, v1, v2;
  #define LG_BUFF 100
  char buff[LG_BUFF];

  v1 = analogRead(A0);
  v2 = analogRead(A5);
  #if 0
  n = sprintf(buff, "v1=%d v2=%d",v1,v2); if (n > LG_BUFF) Serial.println("Buffer overflow");
  Serial.println("Send mqtt data");
  client.publish("test1",buff);
  #else
  n = sprintf(buff, "%d",v1); if (n > LG_BUFF) Serial.println("Buffer overflow");
  client.publish("lumina",buff);
  Serial.print("lumina=");Serial.print(buff);
  n = sprintf(buff, "%d",v2); if (n > LG_BUFF) Serial.println("Buffer overflow");
  client.publish("temp",buff);
  Serial.print(", temperatura=");Serial.println(buff);
  #endif
}


void setup()
{
  cnt1 = 0;
  cnt2 = 0;
  cnt3 = 0;
  cnt4 = 0;
  
  delay(1000);
  Serial.begin(9600);
  watchdogSetup();
  Serial.println("Start arduino. Achizitie + MQTT + ENC28J60");

   pinMode(5, OUTPUT);  //LED Infrared
   pinMode(6, OUTPUT);
   pinMode(7, OUTPUT);
   pinMode(8, OUTPUT);
   //digitalWrite(5, HIGH);  //LED Infrared
   digitalWrite(5, LOW);     //LED Infrared
   
   digitalWrite(6, LOW);
   digitalWrite(7, LOW);
   digitalWrite(8, LOW);

  client.setServer(server, 1883);
  client.setCallback(callback);
  Ethernet.begin(mac, ip);
  wdt_reset();
  delay(1500);
  wdt_reset();
  Serial.print("IP=");Serial.println(Ethernet.localIP());

  analogReference(DEFAULT); // the default analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards) 
  //umax = 4.27;
}


void loop()
{
  wdt_reset();
 #if 1
  //mqtt
  if (!client.connected()) {reconnect();}
  client.loop();
  cnt1++;
  if(cnt1 > 10000) {
    cnt1=0;
    sendMQTT_Data();
  }
#endif
  
#if 1
//aprinde LED=uri
cnt3++;
if (cnt3 > 5000){
  cnt3 = 0;
  digitalWrite(6, cnt4 == 0);
  digitalWrite(7, cnt4 == 1 || cnt4 == 3);
  digitalWrite(8, cnt4 == 2);
  cnt4 ++;
  if(cnt4==4)cnt4=0;
}
#endif




} //end main loop



//MQTT reconnect
void reconnect() {
  wdt_reset();
  // Loop until we're reconnected
  while (!client.connected()) {
    wdt_reset();
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      //client.publish("outTopic","hello world");
      // ... and resubscribe
      //mqtt2rrdclient.subscribe("test2");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again");
      wdt_reset();delay(1000);
      wdt_reset();delay(1000);
      wdt_reset();delay(1000);
    }
  }
}



Rezultatul programului se vede in teminalul serial:

arduino-com7



Ultimele pagini: RSS

Alte adrese de Internet

Categorii

Istoric



Contorizari incepand cu 9 iunie 2014:
Flag Counter
Serviciul DNS este oferit gratuit de Free DNS.

Atentie: Continutul acestui server reprezinta ideile mele si acestea pot fi gresite.