Aller au contenu


Photo
- - - - -

Interface avec un ENC28J60


  • Veuillez vous connecter pour répondre
2 réponses à ce sujet

#1 buildrobot

buildrobot

    Membre occasionnel

  • Membres
  • Pip
  • 89 messages
  • Gender:Male
  • Interests:Robotique humanoïde, programmation arduino, musique

Posté 04 juillet 2018 - 11:01

Bonjour,

 

J'ai acheté un Shield Ethernet ENC28J60 (datasheet : https://www.mouser.c...9662b-62019.pdf )modulo-ethernet-enc28j60-arduino-D_NQ_NP .

 

Je souhaiterai créer une interface web me permettant de contrôler différents éléments de mon Arduino Uno (comme des LEDs, changer la valeurs de variable, jouer des sons...)

 

Pour cela, j'utilise la bibliothèque EtherCard.h.

 

Pour l'instant, j'ai une simple interface permettant de change la couleur du led RGB de chez Adafruit, avec 3 boutons. 

 

Mon problème vient ensuite.

 

Lorsque je veux rajouter d'autres boutons (par exemple pour gérer la difficulté d'un jeu ou jouer des sons), ma page web ne fonctionne plus...

 

Voici mon code fonctionnel :

#include <EtherCard.h>
#include <PololuLedStrip.h>

#define LED_COUNT 1   //Number of led connected
#define LED1 4  // define LED pin
PololuLedStrip<4> ledStrip;
rgb_color colors[LED_COUNT];


static byte myip[] = { 192, 168, 2, 177 };                      // ethernet interface ip address
static byte gwip[] = { 192, 168, 1, 254 };                      // gateway ip address
static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 };   // ethernet mac address - must be unique on your network

bool boolLedR = false;
bool boolLedG = false;
bool boolLedB = false;
byte Red = 0, Green = 0, Blue = 0;

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer
BufferFiller bfill;

void setup() {
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println( "Failed to access Ethernet controller");
  ether.staticSetup(myip, gwip);


  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
}

//En tête HTML
const char http_OK[] PROGMEM =
  "HTTP/1.0 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "Pragma: no-cache\r\n\r\n";

const char http_Found[] PROGMEM =
  "HTTP/1.0 302 Found\r\n"
  "Location: /\r\n\r\n";

const char http_Unauthorized[] PROGMEM =
  "HTTP/1.0 401 Unauthorized\r\n"
  "Content-Type: text/html\r\n\r\n"
  "<h1>401 Unauthorized</h1>";

//Principal page of my interface
void homePage()
{
  bfill.emit_p(PSTR("$F"
                    "<html>"
                    "<head>"
                    "<title>Escape Dimension</title>"
                    "<meta http-equiv='refresh' content='5'/>"
                    "</head>"

                    "<body>"
                    "<h1 style='text-align:center'> Game master </h1>"
                    "<div style='border-style: solid'>"
                    "Color led :"
                    "<button><a href=\"?ledr=$F\">$F</a></button>"
//L'ajout de ces trois boutons (ou même d'un seul) arrête de faire fonctionne mon programme...
//                    "<button>Difficulte 1</button>"
//                    "<button>Difficulte 2</button>"
//                    "<button>Difficulte 3</button>"

                    "</div>"
                    "</body>"
                    "</html>"
                   ),
               http_OK,
               boolLedR ? PSTR("off") : PSTR("on"),
               boolLedR ? PSTR("RED allume") : PSTR("RED eteint"),
               boolLedG ? PSTR("off") : PSTR("on"),
               boolLedG ? PSTR("GREEN allume") : PSTR("GREEN eteint"),
               boolLedB ? PSTR("off") : PSTR("on"),
               boolLedB ? PSTR("BLUE allume") : PSTR("BLUE eteint")
              );
}

void loop() {
  colors[0] = rgb_color(Green, Red, Blue);
  ledStrip.write(colors, LED_COUNT);


  // wait for an incoming TCP packet, but ignore its contents
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

  if (pos) {
    delay(1);   // necessary for my system
    bfill = ether.tcpOffset();
    char *data = (char *) Ethernet::buffer + pos;

    if (strncmp("GET /", data, 5) != 0) {
      // Unsupported HTTP request
      // 304 or 501 response would be more appropriate
      bfill.emit_p(http_Unauthorized);
    }
    else {
      data += 5;

      if (data[0] == ' ') {
        // Return home page
        homePage();
      }
      else if (strncmp("?ledr=on", data, 8) == 0) {
        // Set boolLedR true and redirect to home page
        boolLedR = true;
        Red = 255;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledr=off", data, 9) == 0) {
        // Set boolLedR false and redirect to home page
        boolLedR = false;
        Red = 0;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledg=on", data, 8) == 0) {
        // Set boolLedR true and redirect to home page
        boolLedG = true;
        Green = 255;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledg=off", data, 9) == 0) {
        // Set boolLedR false and redirect to home page
        boolLedG = false;
        Green = 0;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledb=on", data, 8) == 0) {
        // Set boolLedR true and redirect to home page
        boolLedB = true;
        Blue = 255;
        bfill.emit_p(http_Found);
      }
      else if (strncmp("?ledb=off", data, 9) == 0) {
        // Set boolLedR false and redirect to home page
        boolLedB = false;
        Blue = 0;
        bfill.emit_p(http_Found);
      }
      else {
        // Page not found
        bfill.emit_p(http_Unauthorized);
      }
    }

    ether.httpServerReply(bfill.position());    // send http response
  }

}

Je vous ai mis en commentaire de ma fonction homePage les boutons qui ne veulent pas fonctionner...

 

J'en viens donc à vous pour savoir si quelqu'un sait d'où pourrait venir le problème



#2 buildrobot

buildrobot

    Membre occasionnel

  • Membres
  • Pip
  • 89 messages
  • Gender:Male
  • Interests:Robotique humanoïde, programmation arduino, musique

Posté 04 juillet 2018 - 11:05

Ou peut être une autre méthode plus simple pour créer mon interface ? :)



#3 buildrobot

buildrobot

    Membre occasionnel

  • Membres
  • Pip
  • 89 messages
  • Gender:Male
  • Interests:Robotique humanoïde, programmation arduino, musique

Posté 10 juillet 2018 - 07:49

J'ai réussi à faire mon interface web, mais dans ce cas ci, je n'arrive pas à contrôler mes différents éléments...

 

Voici mon code :

#include <EtherCard.h>

const char SSDP_RESPONSE[] PROGMEM = "HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=1200\r\nEXT:\r\nSERVER:Arduino\r\nST: upnp:rootdevice\r\nUSN: uuid:abcdefgh-7dec-11d0-a765-7499692d3040\r\nLOCATION: http://"; //dont forget our mac adress USN: uuid:abcdefgh-7dec-11d0-a765-Mac addr
const char SSDP_RESPONSE_XML[] PROGMEM = "/??\r\n\r\n"; // here is the adress of xml file /?? in this exemple but you could use another /upnp.xml\r\n\r\n
const char XML_DESCRIP[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\n\r\n<?xml version='1.0'?>\r<root xmlns='urn:schemas-upnp-org:device-1-0'><device><deviceType>urn:schemas-upnp-org:device:BinaryLight:1</deviceType><presentationURL>/</presentationURL><friendlyName>Arduino</friendlyName><manufacturer>Fredycpu</manufacturer><manufacturerURL>http://fredycpu.pro</manufacturerURL><serialNumber>1</serialNumber><UDN>uuid:abcdefgh-7dec-11d0-a765-7499692d3040</UDN></device></root>     ";
const char SSDP_NOTIFY[] PROGMEM = "NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=1200\r\nNT: upnp:rootdevice\r\nUSN: uuid:abcdefga-7dec-11d0-a765-7499692d3040::upnp:rootdevice\r\nNTS: ssdp:alive\r\nSERVER: Arduino UPnP/1.0\r\nLOCATION: http://"; //dont forget our mac adress USN: uuid:abcdefgh-7dec-11d0-a765-Mac addr

static byte myip[] = {
  192, 168, 2, 177
};
static byte gwip[] = {
  192, 168, 2, 254
};
static byte ssdp[] = {
  239, 255, 255, 250
};
static byte mymac[] = {
  0x74, 0x99, 0x69, 0x2D, 0x30, 0x40
}; // if you change it you must update SSDP_RESPONSE and XML_DESCRIP

byte Ethernet::buffer[750]; // tcp ip send and receive buffer
unsigned long timer = 9999;
const char pageA[] PROGMEM =
  "HTTP/1.0 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "\r\n"
  "<html>"
  "<head><title>"
  "multipackets Test"
  "</title></head>"
  "<body>"
  "<h1 style='text-align:center'> Game master </h1>"
  "<div style='border-style: solid; padding: 5px;'>"
  "<h2 style='text-align: center; margin: none'>Configuration</h2>"
  "Couleur led :"
  "<button>Rouge</button>"
  "<button>Vert</button>"
  "<button>Bleu</button><br>"
  "Difficulte :"
  "<button>1</button>"
  "<button>2</button>"
  "<button>3</button><br>"

  ;
const char pageB[] PROGMEM =
  "<ul>"
  "Nombre de sons par sequence :"
  "<li>Niveau 1</li>"
  "<ul>"
  "<li>Sequence 1 : <input type='number' min='0' max='20' step='1' value='5' size='6'> sons</li>"
  "<li>Sequence 2 : <input type='number' min='0' max='20' step='1' value='10' size='6'> sons</li>"
  "<li>Sequence 3 : <input type='number' min='0' max='20' step='1' value='15' size='6'> sons</li>"
  "</ul>"
  ;
const char pageC[] PROGMEM =
  "<li>Niveau 2</li>"
  "<ul>"
  "<li>Sequence 1 : <input type='number' min='0' max='20' step='1' value='5' size='6'> sons</li>"
  "<li>Sequence 2 : <input type='number' min='0' max='20' step='1' value='10' size='6'> sons</li>"
  "<li>Sequence 3 : <input type='number' min='0' max='20' step='1' value='15' size='6'> sons</li>"
  "</ul>"
  ;
const char pageD[] PROGMEM =
  "<li>Niveau 3</li>"
  "<ul>"
  "<li>Sequence 1 : <input type='number' min='0' max='20' step='1' value='5' size='6'> sons</li>"
  "<li>Sequence 2 : <input type='number' min='0' max='20' step='1' value='10' size='6'> sons</li>"
  "<li>Sequence 3 : <input type='number' min='0' max='20' step='1' value='15' size='6'> sons</li>"
  "</ul>"
  "</ul>"
  ;

const char pageE[] PROGMEM =
  "<button>Valider la configuration</button>"
  "</div>"
  "<br>"
  "<div style='border-style: solid; padding: 5px;''>"
  "<h2 style='text-align: center; margin: none'>Actions</h2>"
  "<button>Commencer le jeu</button><br>"
  "Jouer un son :"
  "<select>"
  "<option>Elephant</option>"
  "<option>Serpent</option>"
  "<option>Singe</option>"
  "<option>Lion</option>"
  "</select>"
  "<button>Jouer</button><br>"
  ;

const char pageF[] PROGMEM =
  "Ouvrir le coffre "
  "<ul>"
  "<li><button>Ouvrir</button> si victoire</li>"
  "<li><button>Ouvrir</button> si defaite</li>"
  "</ul><br>"
  "Niveau du jeu :"
  "<ol>"
  "<li><input type='checkbox'></li>"
  "<li><input type='checkbox'></li>"
  "<li><input type='checkbox'></li>"
  "</ol>"
  ;

//const char pageG[] PROGMEM =

void setup() {
  ether.begin(sizeof Ethernet::buffer, mymac , SS);// SS = 53 for the mega ethernet shield and  10 for normal ethernet shield
  ether.staticSetup(myip, gwip);
  ENC28J60::disableMulticast(); //disable multicast filter means enable multicast reception
  Serial.begin(115200);
}

void loop() {
wait:
  word pos = ether.packetLoop(ether.packetReceive());
  // check if valid tcp data is received
  if (pos) {
    char* data = (char *) Ethernet::buffer + pos;
    if (strncmp("GET / ", data, 6) == 0) {
      ether.httpServerReplyAck(); // send ack to the request
      memcpy_P(ether.tcpOffset(), pageA, sizeof pageA); // send first packet and not send the terminate flag
      ether.httpServerReply_with_flags(sizeof pageA - 1, TCP_FLAGS_ACK_V);
      memcpy_P(ether.tcpOffset(), pageB, sizeof pageB); // send second packet and not send the terminate flag
      ether.httpServerReply_with_flags(sizeof pageB - 1, TCP_FLAGS_ACK_V);
      memcpy_P(ether.tcpOffset(), pageC, sizeof pageC); // send thirdt packet and not send the terminate flag
      ether.httpServerReply_with_flags(sizeof pageC - 1, TCP_FLAGS_ACK_V);
      memcpy_P(ether.tcpOffset(), pageD, sizeof pageD); // send fourth packet and not send the terminate flag
      ether.httpServerReply_with_flags(sizeof pageD - 1, TCP_FLAGS_ACK_V);
      memcpy_P(ether.tcpOffset(), pageE, sizeof pageE); // send fourth packet and not send the terminate flag
      ether.httpServerReply_with_flags(sizeof pageE - 1, TCP_FLAGS_ACK_V);
      memcpy_P(ether.tcpOffset(), pageF, sizeof pageF); // send fourth packet and send the terminate flag
      ether.httpServerReply_with_flags(sizeof pageF - 1, TCP_FLAGS_ACK_V | TCP_FLAGS_FIN_V);
      goto wait;
    }
    if (strncmp("GET /??", data, 7) == 0) { // description of services (normaly an xml file but here .....)
      ether.httpServerReplyAck();
      memcpy_P(Ethernet::buffer + TCP_OPTIONS_P, XML_DESCRIP, sizeof XML_DESCRIP);
      ether.httpServerReply_with_flags(sizeof XML_DESCRIP - 1 , TCP_FLAGS_ACK_V | TCP_FLAGS_FIN_V);
      goto wait;
    }
    if (strncmp("M-SEARCH", data, 8) == 0) { // service discovery request comes here (udp protocol)
      ssdpresp();
      goto wait;
    }
  }
  if (((millis() - timer) > 50000) || (timer > millis())) {
    timer = millis();
    ssdpnotify();
  }
}

void ssdpresp() { //response to m-search
  byte ip_dst[IP_LEN];
  unsigned int port_dst = Ethernet::buffer[34] * 256 + Ethernet::buffer[35]; //extract source port of request
  for (  int i = 0; i < IP_LEN; i++) { //extract source IP of request
    ip_dst[i] = Ethernet::buffer[i + 26];
  }
  int udppos = UDP_DATA_P;

  EtherCard::udpPrepare(1900, ip_dst, port_dst);
  memcpy_P(Ethernet::buffer + udppos, SSDP_RESPONSE, sizeof SSDP_RESPONSE);
  udppos = udppos  + sizeof SSDP_RESPONSE - 1;
  addip(udppos);
}

void ssdpnotify() { //Notification
  int udppos = UDP_DATA_P;
  EtherCard::udpPrepare(1900, ssdp, 1900);
  memcpy_P(Ethernet::buffer + udppos, SSDP_NOTIFY, sizeof SSDP_NOTIFY);
  udppos = udppos  + sizeof SSDP_NOTIFY - 1;
  addip(udppos);
}

void addip(int udppos) { // add current ip to the request and send it
  int adr;
  for (int i = 0; i < IP_LEN; i++) { // extract the current ip of arduino
    adr = ether.myip[i] / 100;
    if (adr)  {
      Ethernet::buffer[udppos] = adr + 48;
      udppos++;
    }
    adr = (ether.myip[i] % 100) / 10;
    if (adr)  {
      Ethernet::buffer[udppos] = adr + 48;
      udppos++;
    }
    adr = ether.myip[i] % 10;
    Ethernet::buffer[udppos] = adr + 48;
    udppos++;
    Ethernet::buffer[udppos] = 46;
    udppos++; //"."
  }
  udppos--;//erase the last point
  memcpy_P(Ethernet::buffer + udppos, SSDP_RESPONSE_XML, sizeof SSDP_RESPONSE_XML);
  udppos = udppos  + sizeof SSDP_RESPONSE_XML;
  udppos--;
  EtherCard::udpTransmit(udppos - UDP_DATA_P); // send all to the computer who make the request on her ip and port who make the request
}

Celui-ci est écrit en brut, directement dans des const char PROGMEM alors que dans le code du premier post, j'utilisé une fonction (homepage() ) dans laquelle j'utilisé la fonction PSTR() me permettant de créer des chaines formatés et ainsi donc de pouvoir récupérer l'état du bouton sur lequel je cliqué.

 

Comment pourrai-je intégrer ces 2 codes en 1 ?

 

Je vous remercie de votre patiente et de votre aide ! :)

 

buildrobot.






1 utilisateur(s) li(sen)t ce sujet

0 members, 1 guests, 0 anonymous users