UDP Befehle Senden

Guten Morgen,
ich habe folgendes Problem: ich möchte einen Arduino nur zum überwachen von ein paar Knöpfen und Temperatur abstellen. Diese Sachen sollen dann an ein Linux Server per UDP geschickt werden. Allerdings finde ich immer nur UDP Server, die dann was zurück schicken. Habe schon folgendes Versucht:

Udp.beginPacket('192.168.178.48', 8888);
Udp.write("informationen");
Udp.endPacket();  
Serial.println("Infos gesendet");

Er sagt beim Kompelieren zwar, dass alles in Ordnung währe aber beim Server kommt nichts an.
Habe auch eine Libary gefunden die komplett darauf ausgelegt ist aber dort funktionieren nicht mal die Beispiele. Im Sketch selber werden aber keine Fehler angezeigt.

Poste mal den vollständigen Code mit dem Du sendest. UDP ist eigentlich kein "Hexenwerk". :slight_smile:

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include <OneWire.h>
#include <Wire.h>
#include <PN532_I2C.h>
#include <PN532.h>

byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {
192,168,178,49 };
byte ip1[] = {
192,168,178,48 };

unsigned int localPort = 8888;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

long previousMillis = 0;
long previousMillis1 = 0;
long interval = 5000;
int rfid_status = 0;
int DS18S20_Pin = 2;
int karte_gefunden = false;
OneWire ds(DS18S20_Pin);
int erste_mal_fuenf = false;

EthernetUDP Udp;
PN532_I2C pn532i2c(Wire);
PN532 nfc(pn532i2c);

float getTemp(){
//returns the temperature from one DS18S20 in DEG Celsius

byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}

ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end

byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad

for (int i = 0; i < 9; i++) { // we need 9 bytes
data = ds.read();

  • }*
  • ds.reset_search();*
  • byte MSB = data[1];*
  • byte LSB = data[0];*
  • float tempRead = ((MSB << 8) | LSB); //using two's compliment*
  • float TemperatureSum = tempRead / 16;*
  • TemperatureSum = TemperatureSum - 1;*
  • return TemperatureSum;*
    }
    void buzzer(void)
    {
  • for(int i = 0; i<80;i++)*
  • {*
  • digitalWrite(7,HIGH);*
  • delay(1);*
  • digitalWrite(7,LOW);*
  • delay(1);*
  • }*
    }
    void card_reader()
    {
  • boolean success;*
  • uint8_t uid[] = {*
  • 0, 0, 0, 0, 0, 0, 0 };*
  • uint8_t uidLength;*
  • success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);*
  • if (success)*
  • {*
  • Serial.println("Found a card!");*
  • Serial.print("UID Length: ");*
  • Serial.print(uidLength, DEC);*
  • Serial.println(" bytes");*
  • Serial.print("UID Value: ");*
  • for (uint8_t i=0; i < uidLength; i++)*
  • {*
  • Serial.print(" 0x");*
    _ Serial.print(uid*, HEX);_
    _
    }_
    _
    Serial.println("");_
    _
    if( uid[0]==0xFD && uid[1]==0x62 && uid[2]==0x92 && uid[3]==0xCC )_
    _
    {_
    _
    Serial.println("Hello Tom!");_
    _
    buzzer();_
    if(rfid_status == 1)
    _
    {_
    rfid_status = 0;
    _
    }_
    _
    else*_
    * {*
    * rfid_status = 1;
    _
    }_
    _
    }_
    _
    else if(uid[0]==0x25 && uid[1]==0xD1 && uid[2]==0x62 && uid[3]==0xE4)_
    _
    {_
    _
    Serial.println("Hello Gast!");_
    _
    buzzer();_
    if(rfid_status == 3 || rfid_status == 0)
    _
    {_
    rfid_status = 2;
    _
    }_
    else if(rfid_status == 1)
    _
    {_
    _
    }_
    _
    else*_
    * {*
    * rfid_status = 0;
    _
    }_
    _
    }_
    _
    else*_
    * {*
    * Serial.println("Hello unkown guy");*
    * buzzer();*
    * buzzer();*
    * if(rfid_status != 1 || rfid_status != 2)
    _
    {_
    rfid_status == 3;
    _
    }_
    else if(rfid_status == 3)
    _
    {_
    rfid_status = 0;
    _
    }_
    _
    }_
    karte_gefunden = true;
    _
    }_
    _
    else*_
    * {*
    * // PN532 probably timed out waiting for a card*
    * Serial.println("Timed out waiting for a card");*
    * }*
    }
    void setup()
    {
    * Ethernet.begin(mac,ip);*
    * Udp.begin(localPort);*
    * Serial.begin(9600);*
    * nfc.begin();*
    * uint32_t versiondata = nfc.getFirmwareVersion();
    _
    if (! versiondata)_
    _
    {_
    _
    Serial.println("Didn't find PN53x board");_
    rfid_status = 5;
    _
    }_
    _
    nfc.setPassiveActivationRetries(0xFF);_
    _
    nfc.SAMConfig();_
    _
    Serial.println("Waiting for an ISO14443A card");_
    _
    }_
    void loop()
    _
    {_
    _
    if(millis() - previousMillis > 5000)_
    _
    {_
    _
    previousMillis = millis();_
    _
    //Sende informationen*_
    * int temp = getTemp();*
    * char test = (char)(((int)'0')+temp);*
    * Serial.println(test);*

* Udp.beginPacket(ip1, 8888);*
* Udp.write("informationen");*
* Udp.endPacket(); *
* Serial.println("Infos gesendet");*
* }*
* if((rfid_status != 5) && (millis() - previousMillis1 > 2000))
_
{_
card_reader();
if(karte_gefunden)
_
{_
_
Udp.beginPacket(ip1, 8888);_
char dig = (char)(((int)'0')+rfid_status);
_
Udp.write(dig);_
_
Udp.endPacket(); _
_
Serial.println("Karte gelesen");_
_
previousMillis1 = millis();_
_
}_
karte_gefunden = false;
_
}_
if((rfid_status == 5) && (erste_mal_fuenf == false))
_
{_
_
Udp.beginPacket(ip1, 8888);_
char dig = (char)(((int)'0')+rfid_status);
_
Udp.write(dig);_
_
Udp.endPacket(); _
_
Serial.println("Karte gfesen"); _
erste_mal_fuenf = true;
_
}_
_
// send a reply, to the IP address and port that sent us the packet we received*_
* //Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());*
* //Udp.write("blablabla");*
* //Udp.endPacket();*
}
[/quote]

Also das hier kann meiner Meinung nach nicht funktionieren.

Udp.write("informationen");

Denn in der der EthernetUdp.h wird diese Funktion so definiert:

virtual size_t write(const uint8_t *buffer, size_t size);

Auch das hier geht auch nicht

    char dig = (char)(((int)'0')+rfid_status);
      Udp.write(dig);

Es fehlt in beiden Fällen die Länge des Puffers. Hier sizeof(dig);

Kann aber auch falsch liegen denn ich bin Umsteiger auf C (++) und deshalb alles andere als ein Profi.
Aber meiner Meinung liegt dies daran.

Es kompiliert ja. Deshalb sollte es da noch eine andere Methode geben, die nur einen Parameter hat. Theoretisch muss man bei einem Null-terminierten String nicht unbedingt die Länge angeben. Man kann solange Daten ausgeben bis der Terminator kommt.

Da das virtual ist, kann es da aber glaube ich sein, dass dann eine Methode aus der Oberklasse verwendet wird und nicht der abgeleiteten Klasse. Kann sein dass es dann schief geht. Würde also nicht schaden wenn man dann den String erst mal als Array definiert und die Länge dann mit strlen() übergibt.

Bei dem hier frage ich mich aber ob das hin-und hercasten wirklich nötig ist:
char dig = (char)(((int)'0')+rfid_status);

Eigentlich kann man auch einen char einfach eine Zahl addieren und diese auch einem char zuweisen.

Das hier gibt z.B. '4' aus (da '0' 48 ist und 48 + 4 = 52):
unsigned char test = 52;
Das ist das gleiche wie test = '0' + 4;

Deshalb sollte es da noch eine andere Methode geben, die nur einen Parameter hat.

So ist es:

virtual size_t write(uint8_t);

Und kompiliert deshalb.
An den Null Terminator hatte ich auch schon gedacht, also braucht diese Funktion theoretisch die Länge nicht.
Aber definiert ist sie mit Längenangabe wenn ein Char Array benutzt werden soll, und wenn dies fehlt wird virtual size_t write(uint8_t); benutzt.

 // Write a single byte into the packet
  virtual size_t write(uint8_t);

Und die schreibt eben nur ein Byte.

Guten Abend
also ich habe den Fehler gefunden: Normalerweise habe ich im Netzwerk zwei IPs für Arduinos vorgesehen. Allerdings hat sich ein Handy sich eine dieser IPs geschnappt. Der Router blockiert dann beide, da er nicht mehr weiß was los ist. Jetzt habe ich die IP für andere Geräte blockiert und damit ist gut.

Wo wir gerade beim Thema INT zu Char sind:
Diese Umrechnung habe ich per Google gefunden. Eingefügt und sie hat funktioniert und gut war :slight_smile: . Allerdings müsste ich jetzt die Werte vom Tempratursensor konvertieren. Das ganze ist allerdings float und ich habe es mit:

    char test[10];
    float temp = getTemp();
    sprintf(test, "%f", temp);

versucht (ebenfalls bei Google gefunden), aber es kommt immer nur ein Fragezeichen raus. Das ganze ist zweistellig, punkt, zweistellig (z.B: 15.59).

Bin leider kein großer C/C++ Programmierer, kann zwar die Grundlagen und das wars. Bin eher mit Python, Java und Perl dabei.

virtual size_t write(uint8_t);

Mhh, dieser Methode kann man keinen String übergeben. Die will einen unsigned char als Parameter und nicht einen unsigned char*

Wenn man in Visual C++ eine Methode so schreibt kommt dieser Fehler:
error C2664: 'write' : cannot convert parameter 1 from 'unsigned char [5]' to 'const unsigned char'

@anon10042157
sprintf() und Konsorten sind auf dem Arduino/AVR für Float nicht implementiert.

Dafür gibt es eine AVR Funktion:
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

Siehe hier für die genaue Erklärung:
http://www.mikrocontroller.net/topic/86391

@Serenifly: Wenn man nicht nachfragt dann versteht man (ich) das nicht

Wir haben hier zwei Funktionen die den gleichen Namen haben:

virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size);

Das sind so Dinge die in Delphi nicht geduldet werden.

Woher weiß der C++ Compiler nun welche gemeint ist, wenn audacity363 diese ohne den size Parameter aufruft ?
Und das funktioniert wohl auch so :fearful:

Ok diese Funktionen sind virtual - könnten also überschrieben worden sein ?

Das ist in C/C++ auch nicht anders als in anderen weit verbreiteten Sprachen wie Visual Basic, Java oder C#. Die Methoden werden durch die Anzahl und Typen der Parameter unterschieden. Wenn man write() mit nur einem Parameter aufruft, versucht er die obere Funktion zu verwenden. Dann muss natürlich noch der Typ passen, was nicht funktioniert wenn man da einen String übergeben will. Wieso sich das trotz des Typen-Konflikts kompilieren lies, kann ich so jetzt nicht sagen. Dass er was in einer anderen Klasse gefunden hat, ist geraten.

@Serenifly Danke das ganze funktioniert jetzt halbwegs...

Jetzt schmiert der Arduino immer nach dem Infos gesendet ab und resetet sich:

    dtostrf(getTemp(), 2, 2, test);
    strcat(infos, test1);
    strcat(infos, test);
    Udp.beginPacket(ip1, 8888);
    Udp.write("bla");
    Udp.endPacket();  
    Serial.println("Infos gesendet");

Du hast die Parameter nicht korrekt verwendet

width ist die Breite der gesamten Zahl. Inklusive eventuellem Vorzeichen, Vorkomma-Stellen, Punkt und Nachkommastellen.

Also z.B. bei rein positiven Zahlen, zwei Vorkomma-Stellen und zwei Nachkommastellen -> 5.