Moduł Ethernet SPI i Shield - iwi - 06-03-2019
Witajcie.
Napisałem programik pod moduł ENC28J60 który działa poprawnie.
Program działa na skrypcie thingspeak
i bazujący na bibliotece EtherCard.h
Kod: // Simple demo for feeding some random data to Pachube.
// 2011-07-08 <jc@wippler.nl>
//
// License: GPLv2
// Handle returning code and reset ethernet module if needed
// 2013-10-22 hneiraf@gmail.com
// Modifing so that it works on my setup for www.thingspeak.com.
// Arduino pro-mini 5V/16MHz, ETH modul on SPI with CS on pin 10.
// Also added a few changes found on various forums. Do not know what the
// res variable is for, tweaked it so it works faster for my application
// 2015-11-09 dani.lomajhenic@gmail.com
#include <EtherCard.h>
...
Natomiast żeby nie było za dużo kabli zakupiłem ethernet shield i niestety nie działa na tej bibliotece.
Mimo ze też działa na SPI to cały czas mam komunikat że brak połączenia z serwerem.
Natomiast ten Ethernet Shield działa na wbudowanej bibliotece
<Ethernet.h
Dlaczego moduł https://botland.com.pl/pl/produkty-wycofane/1217-arduino-ethernet-shield-z-czytnikiem-kart-microsd.html
nie działa z biblioteką EtherCard.h
Co trzeba zmienić żeby to odpaliło.
Piny SPI sa dokładnie takie same. CS też jest na 10 - nawet ręcznie próbowałem ustawić CS na 10 też nie odpala.
Problem w tym, że już sporo napisałem kodu i nie tak prosto podmienić tą bibliotekę.
Przykładowy kod działający a Thingspeak na shieldzie.
Kod: #include <Timers_akcja.h>
#include <SPI.h>
#include <Ethernet.h>
int pin = 0; // analog pin
float tempc = 0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i;
Timers_akcja <3> Akcja;
// Local Network Settings
byte mac[] = { 0xD4, 0xA8, 0xE2, 0xFE, 0xA0, 0xA1 }; // Must be unique on local network
byte ip[] = { 172,16,100,198 }; // Must be unique on local network
byte gateway[] = { 172,16,100,1};
byte subnet[] = { 255, 255, 255, 0 };
// ThingSpeak Settings
char thingSpeakAddress[] = "api.thingspeak.com";
String writeAPIKey = "A6D0VZ91IT6URB0L"; // Write API Key for a ThingSpeak Channel
const int updateInterval = 10000; // Time interval in milliseconds to update ThingSpeak
String analogPin0;
// Variable Setup
long lastConnectionTime = 0;
boolean lastConnected = false;
int failedCounter = 0;
int led1 = 13;
// Initialize Arduino Ethernet Client
EthernetClient client;
void setup()
{
Serial.begin(57600);
Ethernet.begin(mac, ip, gateway, subnet);
delay(1000);
Serial.print("ETHERNET SHIELD ip is : ");
Serial.println(Ethernet.localIP());
// Start Ethernet on Arduino
startEthernet();
Akcja.attach (0, 10000, update_thingspeak);
}
void loop()
{
Akcja.process(); //włączenie timerów
// tempc = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
tempc = ( 5.0 * analogRead(pin)) / 1024.0;
analogPin0 = String(tempc);
//Serial.println(analogPin0);
// Print Update Response to Serial Monitor
if (client.available())
{
char c = client.read();
Serial.print(c);
}
// Disconnect from ThingSpeak
if (!client.connected() && lastConnected)
{
Serial.println();
Serial.println("...disconnected.");
Serial.println();
client.stop();
}
// Update ThingSpeak
if(!client.connected() && (millis() - lastConnectionTime > updateInterval))
{
updateThingSpeak("field1="+analogPin0);
}
lastConnected = client.connected();
}
//============================================= MOJE FUNKCJE =================================================================
void updateThingSpeak(String tsData)
{
if (client.connect(thingSpeakAddress, 80))
{
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(tsData.length());
client.print("\n\n");
client.print(tsData);
lastConnectionTime = millis();
if (client.connected())
{
Serial.println("Connecting to ThingSpeak...");
Serial.println();
failedCounter = 0;
}
else
{
failedCounter++;
Serial.println("Connection to ThingSpeak failed ("+String(failedCounter, DEC)+")");
Serial.println();
}
}
else
{
failedCounter++;
Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter, DEC)+")");
Serial.println();
lastConnectionTime = millis();
}
}
void startEthernet()
{
client.stop();
Serial.println("Connecting Arduino to network...");
Serial.println();
delay(1000);
// Connect to network amd obtain an IP address using DHCP
if (Ethernet.begin(mac) == 0)
{
Serial.println("DHCP Failed, reset Arduino to try again");
Serial.println();
}
else {
Serial.println("Arduino connected to network using DHCP");
Serial.println();
Serial.println("Data being uploaded to THINGSPEAK Server.......");
Serial.println();
}
delay(1000);
}
void update_thingspeak()
{
updateThingSpeak("field4="+analogPin0);
}
RE: Moduł Ethernet SPI i Shield - kaczakat - 06-03-2019
Nic nie szkodzi, napisz jeszcze raz, może tym razem ze zrozumieniem. Dla shielda nie podajesz pinów bo ich się nie zmienia. Wgraj przykładowy szkic i sprawdź czy jest sprawny - jakiś serwer np. Przy okazji zobaczysz co jest niezbędne do wystartowania w sieci, jest tu "Ethernet.begin(mac, ip);", no u Ciebie jeszcze brama, itp. , ale po co znowu to robisz w funkcji startEthernet()? Startujesz na stałym IP, potem chcesz na DHCP?
W swoim kodzie masz obliczanie interwałów czasu wysłania przez millis i jednocześnie przypisanie akacji wg biblioteki Timers_akcja (nie mam jej i nie sprawdzę u siebie, ale to bez sensu).
Jak wejdziesz na thinkspeak to tam też są przykłady jak ma wyglądać kod.
Po prostu otwórz sobie przykład klienta i tylko dodaj thinkspeak, w sumie thinkspeak to może być jedna funkcja, ja używam wersji z GET zamiast POST.
I zmień sobie klucz writeAPIKey po tej publikacji, takie zmienne lepiej dołączać z osobnego pliku, np. hasla.h, wgrywasz do tego samego katalogu jak używany szkic, inkludujesz jak plik biblioteki i nie musisz klepać za każdym razem (ani zdradzać).
RE: Moduł Ethernet SPI i Shield - iwi - 06-03-2019
Ten przykład co podałem to jest wzięty z sieci.
Moduły oba są sprawne i oba na tym samym chipsecie ENC28J60. Jednego jak podłączam i podpinam bibliotekę jedną to działa a z drugą nie. Z drugim jest na odwrót - na pierwszej bibliotece nie działa a na drugiej działa.
Piny są dokładnie te same zarówno w bibliotece pierwszej jak i drugiej .
Arduino UNO
// SCK - Pin 13
// SO - Pin 12
// SI - Pin 11
// CS - Pin 10
Dlaczego to nie działa zamiennie - nie wiem, ale próbuję dojść do tego.
Też się dziwię po co jest przypisanie IP i jednocześnie z DHCP - tak był zrobiony przykład - może po to że jak DHCP nie zadziała to weźmie ustawienia te przypisane.
Ta biblioteka timer_akcja jest wyłączona - robiłem tylko próby na niej. - powinno być zakomentowane wywołanie.
Przeglądałem pliki biblioteki ethernet i ethercard i próbuje dojść do ładu z nimi czym się różnią i dlaczego to nie działa
Interesuje mnie żeby działało z Shieldem bo docelowo na nim chcę pozostać
Błąd się pojawia przy inicjalizacji
Kod: if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0){
Serial.println( "Failed to access Ethernet controller");
continue;
}
Czyli nie ma odpowiedzi z Shielda bo na terminalu cały czas mam komunikat
Failed to access Ethernet controller
Funkcja wygląda tak
Kod: uint8_t EtherCard::begin (const uint16_t size,
const uint8_t* macaddr,
uint8_t csPin) {
using_dhcp = false;
#if ETHERCARD_STASH
Stash::initMap();
#endif
copyMac(mymac, macaddr);
return initialize(size, mymac, csPin);
}
ETHERCARD_STASH jest ustawiony na 1.
RE: Moduł Ethernet SPI i Shield - kaczakat - 06-03-2019
No oba nie są na tym samym chipie, z linku jest 5100, nie ma go bo teraz jest pewnie 5500, ale działa tak samo. Do ENC28J60 używałeś przykładów z biblioteki Ethercard, do WS5100 używasz z Ethernet.
Otworzyłem przykład WebClient z Ethernet, wgrałem i działa od strzału (DHCP, przyznany IP jest drukowany na Serial). Próbowałeś od tego zacząć? Zamieniłem serwer google na thinkspeak, wgrałem używane funkcje z ESP, zamieniłem tylko obiekt klienta z WIFI na Ethernet i dalej działa. Zacznij od początku, po co definiujesz SS skoro może działać na domyślnym ustawieniu. Przypuszczam, że lepiłeś to tygodniami i teraz żal, ale przeróbki mogą trwać dłużej, do wykorzystania jest tylko ta część z thinkspeak.
RE: Moduł Ethernet SPI i Shield - iwi - 06-03-2019
(06-03-2019, 18:54)kaczakat napisał(a): No oba nie są na tym samym chipie, z linku jest 5100, nie ma go bo teraz jest pewnie 5500, ale działa tak samo. Do ENC28J60 używałeś przykładów z biblioteki Ethercard, do WS5100 używasz z Ethernet.
Otworzyłem przykład WebClient z Ethernet, wgrałem i działa od strzału (DHCP, przyznany IP jest drukowany na Serial). Próbowałeś od tego zacząć? Zamieniłem serwer google na thinkspeak, wgrałem używane funkcje z ESP, zamieniłem tylko obiekt klienta z WIFI na Ethernet i dalej działa. Zacznij od początku, po co definiujesz SS skoro może działać na domyślnym ustawieniu. Przypuszczam, że lepiłeś to tygodniami i teraz żal, ale przeróbki mogą trwać dłużej, do wykorzystania jest tylko ta część z thinkspeak.
OK dziękuję za informacje.
Dlatego tak walczę bo kilka tygodni walczyłem z kodem żeby naprzemiennie wysyłał dane raz na pvmonitor.pl a raz na moją stronę na innym serwerze i zapisywał dane do mysqla
Dodatkowo sprawdza czy ktoś na stronie nie przełączył przycisku i w razie wystąpienia zmiany ma wysterować wyjście przekaźnikowe.
PVmonitor nie daje pełnych statystyk więc tam chcę kontynuować historycznie dane które wysyłam z LanKontrolera, a moja strona ma już robić pełne zestawienia i statystyki plus sterowanie wejściami/wyjściami
na razie strony do testów:
http://www.iwi.gsm.pl/arduino/
http://www.iwi.gsm.pl/arduino2/
Ale wracając do przykładu.
W tym przykładzie z biblioteką ethernet.h wysyła się dane funkcją get
a w ethercard jest jakim post. Dodatkowo jest jakiś PSTR co nie wiadomo co z nim zrobić.
funkcja działająca na starym kontrolerze wyglądała tak:
Kod: void thingspeak_start(void) {
int myInt = temperature;
char myIntAsString[7];
itoa(myInt, myIntAsString, 10);
res = res + 1;
ether.packetLoop(ether.packetReceive());
//200 res = 10 seconds (50ms each res)
if (res == 200) {
// generate two fake values as payload - by using a separate stash,
// we can determine the size of the generated message ahead of time
// field1=(Field 1 Data)&field2=(Field 2 Data)&field3=(Field 3 Data)&field4=(Field 4 Data)&field5=(Field 5 Data)&field6=(Field 6 Data)&field7=(Field 7 Data)&field8=(Field 8 Data)&lat=(Latitude in Decimal Degrees)&long=(Longitude in Decimal Degrees)&elevation=(Elevation in meters)&status=(140 Character Message)
byte sd = stash.create();
stash.print("field1=");
stash.print(myIntAsString);
stash.print("&field2=");
stash.print(13);
stash.print("&field3=");
stash.print(temperature);
stash.save();
//Display data to be sent
Serial.print("temperatura: ");
Serial.println(myIntAsString);
// generate the header with payload - note that the stash size is used,
// and that a "stash descriptor" is passed in as argument using "$H"
Stash::prepare(PSTR("POST /update HTTP/1.0" "\r\n"
"Host: $F" "\r\n"
"Connection: close" "\r\n"
"X-THINGSPEAKAPIKEY: $F" "\r\n"
"Content-Type: application/x-www-form-urlencoded" "\r\n"
"Content-Length: $D" "\r\n"
"\r\n"
"$H"),
website2, PSTR(APIKEY), stash.size(), sd);
Serial.println(sd);
// send the packet - this also releases all stash buffers once done
session = ether.tcpSend();
// added from: http://jeelabs.net/boards/7/topics/2241
int freeCount = stash.freeCount();
if (freeCount <= 3) { Stash::initMap(56); }
}
const char* reply = ether.tcpReply(session);
if (reply != 0) {
res = 0;
Serial.println(F(" >>>REPLY recieved...."));
Serial.println(reply);
}
delay(300);
}
Może masz rację że chyba trzeba napisać od nowa bo przerobienie tego nie widzę.
RE: Moduł Ethernet SPI i Shield - kaczakat - 07-03-2019
Właśnie dlatego używam GET bo mam lankontroler, on miał możliwość wysyłania danych na thinkspeak tylko tak. I pomimo, że mam już podobne rozwiązania z Arduino to szkoda mi było wyrzucić, a przy okazji działa mi lepiej również na Arduino. Już to wklejałem wiele razy na różne fora, tym razem na bazie ethernet:
Kod: #include <SPI.h>
#include <Ethernet.h>
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni;
bool fnTik,fsekundy,fminuty,fgodziny,fdni;
const char* serverthink = "api.thingspeak.com";
String apiKey ="";
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192, 168, 1, 1);
void setup() {
Serial.begin(115200);
lanStart();
}
void loop()
{
czas();
if(fminuty&&(!(minuty%2))) //co dwie minuty
{
sendTeperatureTS(nTik,sekundy,minuty,godziny,dni);//po prostu wysylam cokolwiek
}
}
void lanStart()
{
// start the Ethernet connection:
Serial.println(F("Initialize Ethernet with DHCP:"));
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println(F("Ethernet shield was not found. Sorry, can't run without hardware. :("));
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println(F("Ethernet cable is not connected."));
}
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip, myDns);
} else {
Serial.print(F(" DHCP assigned IP "));
Serial.println(Ethernet.localIP());
}
// give the Ethernet shield a second to initialize:
delay(1000);
}
void sendTeperatureTS(float tempera1, float tempera2, float tempera3, float tempera4, uint8_t minutki)
{
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
if (client.connect(serverthink, 80)) { // use ip 184.106.153.149 or api.thingspeak.com
Serial.println(F("Polaczono z Thinkspeak "));
String getStr= F("GET https://api.thingspeak.com/update?api_key=");
getStr += apiKey;
getStr += "&field1=";
getStr += String(tempera1);
getStr += "&field2=";
getStr += String(tempera2);
getStr += "&field3=";
getStr += String(tempera3);
getStr += "&field4=";
getStr += String(tempera4);
getStr += "&field5=";
getStr += String(minutki);
getStr += "\r\n";
client.print(getStr);
Serial.println(F("Cos tam probowano wyslac"));
}//end if
client.stop();
}//end send
void czas()
{
czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik)
{
czasPoprzedni=czasTeraz;
fnTik=1;
nTik++;
if(nTik>=(1000/tik))
{
nTik=0;
sekundy++;
fsekundy=1;
if (sekundy>=60)
{
sekundy=0;
minuty++;
fminuty=1;
if (minuty>=60)
{
minuty=0;
godziny++;
fgodziny=1;
if (godziny>=24)
{
godziny=0;
fdni=1;
dni++;
}
}
}
}
}
}
RE: Moduł Ethernet SPI i Shield - iwi - 08-03-2019
Dziękuję.
Wysyłanie super działa, ale z odbieraniem mam problemy.
W moim starym kodzie robiłem to przez callbacka i odbierałem dane do określonego bufora.
W tym przykładzie Ethernet nie jest klasą i nie można zadeklarować Ethernet::buffer[500];
Dałem do funkcji LOOP
if (client.available()) {
char c = client.read();
Serial.print©;
}
i teoretycznie powinno działać ale nie działa. W każdym razie nic nie wypisuje.
RE: Moduł Ethernet SPI i Shield - kaczakat - 08-03-2019
Ja to zrobiłem na bazie przykładu ethernet klient z Arduino, pewnie brakuje Ci tej części, którą wykasowałem z loop, bo mi nie było do niczego potrzebne odbieranie. Jak tam zajrzysz to znajdziesz.
RE: Moduł Ethernet SPI i Shield - iwi - 08-03-2019
no nie do końca.
Jest co prawda takie coś
if (client.available()) {
char c = client.read();
Serial.print©;
}
ale za każdym razem w funkcji dajesz
client.stop();
więc to nie zadziała.
Z drugiej strony jak wejdziemy i zapiszemy to w funcji to odczyta tylko jeden znak. Na razie nie mam pojęcia jak to ugryźć żeby tylko raz na 2 minuty odczytywał bufor a nie ciągle
a nawet jakbym wywalił client.stop to jak to zrobić żeby w LOOP po odczytaniu powiedzmy 100 znaków zrobił client.stop.
RE: Moduł Ethernet SPI i Shield - kaczakat - 08-03-2019
Ale jak masz jedną funkcję do klient write, to możesz sobie zrobić analogiczną funkcję do klient read, w parzystych sekundach się uruchamia write, to w nieparzystych odpal read.
|