Ingressi e Parametri di rete

Ciao a tutti e complimenti…
Piccola domanda da un profano
Vorrei realizzare un piccolo progetto dove ho 2 ingressi ed una uscita che variano tramite un hardware esterno (antifurto).
Praticamente vorrei attivare il mio antifurto chiudendo un ingresso di quest’ultimo, attivando con il mio mio Arduino 2009 un suo ingresso, il tutto da remoto tramite smartphone utilizzando una app.
Ho installato la mia shield ethernet (non quella ufficiale ma quella con il chip enc28J60 ) ed ho verificato il funzionamento con un esempio presente nella libreria, e sembra funzionare egregiamente.
Ora non riesco ad inserire nello stetck di esempio l’abilitazione dei miei due ingressi digitali.
Probabilmente, anzi sicuramente sbaglio, ma non riesco a capire dove.
In definitiva dovrei settare questo ip
192.168.1.33
gw 192.168.1.1
dns 8.8.8.8
Questo il mio esempio ma non sono riuscito
Vi ringrazio anticipatamente chi mi vorrà aiutare
Grazie

// This demo does web requests to a fixed IP address, using a fixed gateway.
// 2010-11-27 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <EtherCard.h>

#define REQUEST_RATE 5000 // milliseconds

// ethernet interface mac address
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = { 192,168,1,33 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };
// remote website ip address and port
static byte hisip[] = { 74,125,79,99 };
// remote website name
const char website[] PROGMEM = "google.com";

byte Ethernet::buffer[300];   // a very small tcp/ip buffer is enough here
static long timer;

// called when the client request is complete
static void my_result_cb (byte status, word off, word len) {
  Serial.print("<<< reply ");
  Serial.print(millis() - timer);
  Serial.println(" ms");
  Serial.println((const char*) Ethernet::buffer + off);
}

void setup () {
  Serial.begin(57600);
  Serial.println("\n[getStaticIP]");
  pinMode(2, INPUT_PULLUP);
  pinMode(8, OUTPUT);
  
   
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");

  ether.staticSetup(myip, gwip);

  ether.copyIp(ether.hisip, hisip);
  ether.printIp("Server: ", ether.hisip);

  while (ether.clientWaitingGw())
    ether.packetLoop(ether.packetReceive());
  Serial.println("Gateway found");
  
  timer = - REQUEST_RATE; // start timing out right away
}

void loop ()
{
  //read the pushbutton value into a variable
  int sensorVal = digitalRead(2);
  //print out the value of the pushbutton
  Serial.println(sensorVal);

  // Keep in mind the pullup means the pushbutton's
  // logic is inverted. It goes HIGH when it's open,
  // and LOW when it's pressed. Turn on pin 13 when the
  // button's pressed, and off when it's not:
  if (sensorVal == HIGH) {
    digitalWrite(8, LOW);
  } else {
    digitalWrite(8, HIGH);
 }
 }
 {
  ether.packetLoop(ether.packetReceive());
  
  if (millis() > timer + REQUEST_RATE) {
    timer = millis();
    Serial.println("\n>>> REQ");
    ether.browseUrl(PSTR("/foo/"), "bar", website, my_result_cb);
  }
}
}

"Chi non muore si rivede" ... 1 POST nel Febbraio 2010 ... ed uno ora ... ::)

Comunque, non avendolo tu ancora fatto, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI ([u]spiegando bene quali conoscenze hai di elettronica e di programmazione[/u] ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

Ciao Guglielmo Hai ragione...mi sono svegliato tardi.. Presentazione fatta aspetto un vostri/tuo aiuto Grazie a tutti :) :) :) :)

Non ho ben capito quello che vuoi fare …
… hai un Arduino con Ethernet shield, da remoto, via App vuoi inviare un comando e … Arduno esattamente cosa deve fare?

Uno schema sintetico, senza tante chiacchiere ma solo con la descrizione temporale degli eventi … così si capisce la funzionalità.

Guglielmo

Ciao e grazie per la risposta Comandare due ingressi tramite App Tutto qui... Hardware arduino 2009 +shield,ethernet con il chip enc28J60 Questo è quanto Grazie ancora Guglielmo

Ok, quindi una cosa molto comune di cu su Google trovi migliaia di esempi ... ... fai questa ricerca "arduino ethernet switch a led" e troverai ... 578'000 risultati :D

Alcuni esempi ti fanno vedere anche come controllare separatamente più LED ... è il tuo caso, solo che al posto dei LED, sui pin digitali, tu collegherai il tuo antifurto (... purché con livelli TTL).

Fammi sapere ;)

Guglielmo

Meglio google arduino ethernet enc28J60

Se remoto significa da fuori casa ti anticipo che il problema principale sarà quello di evitare che altri accedano al tuo arduino e attivino il tuo antifurto.

Grazie a tutti per le risposte
Ho trovato diversi esempi di progetti ma quando li compilo mi danno sempre un sacco di errori oppure il più semplice Memoria esaurita…Atmel 168 ( è un pò pochino).
E’ possibile con l’hardware che ho far si che funzioni…?
Quando carico non riesco neanche a pingare l’arduino…
Dov’è l’inghippo…
Grazie

#include <EtherCard.h>

static byte mymac[] = {0xDD,0xDD,0xDD,0x00,0x00,0x01};
static byte myip[] = {192,168,1,2};
byte Ethernet::buffer[700];

const int ledPin = 2;
boolean ledStatus;

char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

void setup () {
 
  Serial.begin(57600);
  Serial.println("WebLed Demo");
 
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 
  if (!ether.staticSetup(myip))
    Serial.println("Failed to set IP address");

  Serial.println();
  
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  ledStatus = false;
}
  
void loop() {
 
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {
    
    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=ON") != 0) {
      Serial.println("Received ON command");
      ledStatus = true;
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=OFF") != 0) {
      Serial.println("Received OFF command");
      ledStatus = false;
    }
    
    if(ledStatus) {
      digitalWrite(ledPin, HIGH);
      statusLabel = on;
      buttonLabel = off;
    } else {
      digitalWrite(ledPin, LOW);
      statusLabel = off;
      buttonLabel = on;
    }
      
    BufferFiller bfill = ether.tcpOffset();
    bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
      "Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
      "<html><head><title>WebLed</title></head>"
      "<body>LED Status: $S "
      "<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
      "</body></html>"      
      ), statusLabel, buttonLabel, buttonLabel);
    ether.httpServerReply(bfill.position());
  }
}

L'Atmel 168 ha la metà della flash di un 328 e la metà di RAM. Inoltre usi l'enc28J60 la cui libreria occupa più spazio di quella del Wiznet5100. Nello sketch che hai allegato il solo buffer occupa 700 byte

byte Ethernet::buffer[700];

Magari puoi provare a ridurlo a 350

Grazie zoomx
Con la modifica suggerita sono riuscito a farlo funzionare…
Ora vi chiedo un ulteriore aiuto,
Anziché un led è possibile comandare un ingresso digitale?
Questo è lo sketch funzionante

#include <EtherCard.h>

static byte mymac[] = {0xDD,0xDD,0xDD,0x00,0x00,0x01};
static byte myip[] = {192,168,1,2};
byte Ethernet::buffer[100];
boolean ledStatus;

char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

void setup () {
 
  Serial.begin(57600);
  Serial.println("WebLed Demo");
 
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 
  if (!ether.staticSetup(myip))
    Serial.println("Failed to set IP address");

  Serial.println();
  
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  ledStatus = false;
}
  
void loop() {
 
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {
    
    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=ON") != 0) {
      Serial.println("Received ON command");
      ledStatus = true;
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=OFF") != 0) {
      Serial.println("Received OFF command");
      ledStatus = false;
    }
    
    if(ledStatus) {
      digitalWrite(ledPin, HIGH);
      statusLabel = on;
      buttonLabel = off;
    } else {
      digitalWrite(ledPin, LOW);
      statusLabel = off;
      buttonLabel = on;
    }
      
    BufferFiller bfill = ether.tcpOffset();
    bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
      "Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
      "<html><head><title>WebLed</title></head>"
      "<body>Attivo Antifurto: $S "
      "<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
      "</body></html>"      
      ), statusLabel, buttonLabel, buttonLabel);
    ether.httpServerReply(bfill.position());
  }
}

Si, se l'ingresso è veramente digitale basta collegare la massa e il pin che ti accende il led, non devi cambiare niente. Controlla però che le tensioni siano compatibili, ad esempio una caldaia non va bene, il segnale di solito è a 24V. Non va bene se l'ingresso accetta una tensione massima inferiore ai 5V, ad esempio 3.3V. Non va bene se l'ingresso assorbe oltre i 20mA. Ci vorrebbero le specifiche dell'ingresso.

Come pensi che tutta quella roba di cui fai emit_p() possa stare in un buffer di soli 100 byte?

Anziché un led è possibile comandare un ingresso digitale?

No, non è possibile forzare i registri del micro a cambiare lo stato di un input (poichè un pin input passa in sola lettura), ci ho già provato, però puoi farlo creando una copia del registro che è un solo byte, chiaro che quando fai questo force dovrai impedire al registro reale di copiare quel bit sul tuo registro virtuale, quel pin sarà ignorato fino a quando non togli il "force" Dovrai smettere di usare i digital.read e lavorare con i registri e i suoi singoli bit

Eh? Lui vuole comandare un ingresso di un altro apparato collegandolo ad un'uscita di Arduino... Certo che è possibile, previo quanto detto da zoomx.

Comandare un ingresso digitale io lo interpreto: microcontrollore > software > pin input

Anche perchè si da il comando a un output non a un input, avrò letto troppo alla lettera :) .

vediamo cosa intendeva, semai levo i post :)

Sì sì, hai ragione, si è espresso in maniera fuorviante, ma se leggi l'intero thread capirai :).

Comunque il concetto di "comandare un input" come lo intendi tu a mio avviso è contorto in partenza :D.

E' di un utilità impressionante invece poter gestire gli input a piacere escludendo in campo tutto ciò che può essere pulsanti, interruttori, microswitc ecc

A livello di gestione dell'impianto da pannello thouch o da pagina web, posso fare, simulazioni e forzature, un po come la centrale d'allarme che in caso di guasto di un sensore faccio da tastiera o da software remoto l' "esclusione zona", che poi non è altro che una forzatura dell'input a stare high qualsiasi cosa succeda.

L'utilizzo dei registri e la loro copia uno sull'altro anchè utilizzare digita.write o read aumenta di parecchio la performance del micro e non sembra ma fa risparmiare un sacco di linee. però mi sa che non è il suo caso :confused:

Beh ok, poter simulare facilmente una certa situazione degli ingressi ai fini del debugging è l'unico utilizzo sensato che vedo nella cosa, ma sarebbe banale da fare anche con un piccolo wrapper di digitalRead().

Usare direttamente i registri è sicuramente utile dal punto di vista delle performance ma, oltre a richiedere conoscenze precise sulla MCU in uso, ti fa perdere la portabilità, che a volte è più importante delle performance.

Comunque tutto ciò in questo contesto non importa :).

Testato, no, Pablos! senza alcun dubbio usare i registri è più rapido ma va fuori dalla filosofia Ardduino. digital.write viene correttamente compilato su Arduino, Esp8266, MSP430, STM32 e così via. Se serve andare più veloce si va con i registri ma se bisogna semplicemente accendere un LED...