Go Down

Topic: Raw UDP on Arduino (Read 825 times) previous topic - next topic

TGDrakaRG

Hello

I need to send Raw UDP messages, and I'm a little confused by various posts in the forum.

I've tried:

byte outBuf[] = {0xF0, 0x43, 0x10, 0x3E, 0x7F, 0x01, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF7};

// This sends all 14 bytes, zeros and all
Udp.write(outBuf, 14);

But this doesn't seem to work...

Any help would be most appreciated!

PaulS

Quote
But this doesn't seem to work...

Your evidence?

TGDrakaRG

I'm trying to send the Raw UDP (over WiFi) back to an iPhone.  When I send messages to the iPhone (over WiFi) using a MAX patcher (using sadam.udpsender) everything works.  Is there any way I can monitor this (I've tried Wireshark, but there's too much traffic).  Is there a Processing example for RawUDP?  I'm sure I'm very close here, not sure what to try next...

PaulS

That was a hint for you to post your code.

TGDrakaRG

Sorry, I didn't get that...

Thanks for your replies!

My hardware setup is:  Arduino Uno, Arduino Ethernet Shield connected to TP-Link Nano Wireless router, MIDI Shield.
My aim is to build a standalone RawUDP->MIDI, MIDI->RawUDP standalone interface using Arduino modules.

The RawUDP part is the issue...  I'm sure it's a small coding error.

Code: [Select]
#include <MIDI.h>
#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0xFC, 0xDD };
IPAddress ip(192,168,0,21);
int led = 6;
unsigned int localPort = 9000;      // local port to listen on
IPAddress destinationIP(192, 168, 0, 223);  // Address of target machine
  unsigned int destinationPort = 9001;      // Port to send to

// buffers for receiving and sending data
char packetBuffer[14]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
   pinMode(led, OUTPUT);
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  //Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
 
     digitalWrite(led, HIGH);
   
    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
   
   
   
   
    // send a reply, to the IP address and port that sent us the packet we received
    delay(10);
    // The message is UDP equivalent of a MIDI SysEx message to turn channel 2 of an 01v96 console ON...
   byte outBuf[] = {0xF0, 0x43, 0x10, 0x3E, 0x7F, 0x01, 0x1A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xF7};

   // This should send all 14 bytes, zeros and all - this is not working!
   Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
   Udp.write(outBuf, 14);
   Udp.endPacket();

   
   
    Serial.flush();
    delay(2);
    Serial.end();
 
// Change the arduino's baud rate to that of MIDI...
 
  Serial.begin(31250);
//Send received string out via MIDI - this is working.
    Serial.write(240);  //F0
  //  Serial.println("SysEx Sent:");
   // Serial.print(240);
    //Serial.print(" ");
    for (int n = 1; n< packetSize - 1; n++)
    {
      Serial.write(packetBuffer[n]);
     // Serial.print(packetBuffer[n], DEC);
     // Serial.print(" ");
    }
    Serial.write(247); //F7
    Serial.flush();
   delay(2);
    Serial.end();
   digitalWrite(led, LOW);
 
     
  }
 
   
  delay(10);
}


I'm receiving fine from the iPhone, and the MIDI is output correctly.  But the UDP send back to the iPhone (which should turn channel 2 on in the iOS App) never gets received. That's my only stumbling block.  Please note, I need the output to be Raw UDP, sent to the correct IP and Port.  I think that's where the problem lies.

Hope you can help!


cwrose

Unfortunately I can't post the whole program, it's too long,
but here's the main loop:
Code: [Select]

/*
** l o o p
**
** Main loop of udpsensor.ino
*/
void loop(void)
{
    double celsius = 0;
    double fahrenheit = 0;
    unsigned int raw = 0;
    byte cneg = false;
    byte fneg = false;
    byte cfg = 0;
    byte chip = 0;
    byte rom[8];
    byte scratch[12];
    char buff[24];
    char udp[MAGIC];
    char buffer[MAGIC / 2];

    //Serial.println("loop()");

    if (!interrupted) return;

    // Get and send the values for each sensor in turn
    for (int idx = 0 ; idx < (addr_idx / 8) ; idx++) {

        memset(buffer, 0, sizeof(buffer));
        memset(udp, 0, sizeof(udp));

        strcpy(buff, "Sensor 0: ");
        buff[7] = (char) ('0' + idx + 1);
        strcat(udp, buff);
        strcat(buffer, buff);

        // Get the current DS1820 ROM code, displaying
        // it with the MSB to the left.
        for (int j = 0 ; j < 8 ; j++) {
            rom[j] = addresses[idx * 8 + j];
#if 0
            sprintf(buff, "%02x", addresses[idx * 8 + 7 - j]);
            strcat(udp, buff);
            strcat(buffer, buff);
        }
#else
            buff[j * 2] = hex[(addresses[idx * 8 + 7 - j] >> 4) & 0xf];
            buff[j * 2 + 1] = hex[addresses[idx * 8 + 7 - j] & 0xf];
        }
        buff[16] = '\0';
        strcat(udp, buff);
        strcat(buffer, buff);
#endif

        // Add spacing to the output
        strcat(buffer, " ");
        strcat(udp, " ");

        // A sensor has been found and needs to be read
        ds.reset();             // Returns 0 on failure, 1 if device present
        ds.select(rom);         // This is the Match Rom command
        ds.write(CONVERT, 1);   // Start conversion, maintain parasitic power
        delay(CVTDLY);          // Maybe 750ms is enough, maybe not
        // We might do a ds.depower() here, but the reset is sufficient
        ds.reset();
        ds.select(rom);
        ds.write(READSCRATCH);  // Read scratchpad
        for (int j = 0 ; j < 9 ; j++)   // get 9 bytes from sensor
            scratch[j] = ds.read();

        // convert the data to an actual temperature
        // This expression has sign-extension problems.
        //raw = (unsigned int) ((scratch[1] << 8) | scratch[0]);
        raw = scratch[1];
        raw <<= 8;
        r = scratch[0] & 0xff;
        raw |= r;

        // We are using a DS18B20, so chip is always 0
        // 0x60 is 01100000, 0x20 is 00100000, 0x10 is 000100000
        if (chip == 0) {
            cfg = (uint8_t) (scratch[4] & 0x60);
            Serial.print("Conversion delay: ");
            Serial.println(CVTDLY);
            Serial.print("Resolution: ");
            if (cfg == 0x00) {      // 9 bit resolution, 93.75 ms
                Serial.println("9-bit");
                raw = raw & ~3u;
            }
            else if (cfg == 0x20) { // 10 bit res, 187.5 ms
                Serial.println("10-bit");
                raw = raw & ~2u;
            }
            else if (cfg == 0x40) { // 11 bit res, 375 ms
                Serial.println("11-bit");
                raw = raw & ~1u;
            }
            // default is 12 bit resolution, 750 ms conversion time
            else {
                Serial.println("12-bit");
            }
        }
        else {
            raw = raw << 3;     // 9 bit resolution default
            if (scratch[7] == 0x10) {
                // count remaining gives full 12 bit resolution
                raw = (raw & 0xFFF0) + 12 - scratch[6];
            }
        }

        // To get 2s-complement negative value, invert and add 1
        if (raw & 0x800) {
            raw = ~raw;
            raw += 1;
            cneg = true;
        }
        else
            cneg = false;

        // At the 12 bit maximum resolution, each bit is 1/16 of a degree C
        raw = raw & 0x7ff;
        celsius = (double) raw / 16.0;
        if (cneg)
            fahrenheit = 32 - celsius * 1.8;
        else
            fahrenheit = 32 + celsius * 1.8;
        if (fahrenheit < 0) {
            fneg = true;
            fahrenheit = - fahrenheit;
        }
        else
            fneg = false;

        buff[0] = cneg ? '-' : '+';
        d2a(celsius, buff + 1);
        strcat(udp, buff);
        strcat(buffer, buff);
        // Is there a way of avoiding this lvalue ???
        uint32_t a = uint32_t(dest);
        send_packet(udp, (byte *) &a, udp_port);

        // There seems no way to print floating point numbers,
        // despite the documentation. The loop simply hangs.
        // d = 1357;
        // c = 5791;
        // double e = 45.67;

        int c = (int) celsius;
        int f = (int) fahrenheit;
       
        strcpy(buff, "  Temperature =  ");
        buff[16] = cneg ? '-' : '+';
        Serial.print(buff);
        Serial.print(c, DEC);
        strcpy(buff, " Celsius,  ");
        buff[10] = fneg ? '-' : '+';
        Serial.print(buff);
        Serial.print(f, DEC);
        Serial.println(" Fahrenheit");

        // Check for low memory levels.
        Serial.print("Free memory: ");
        Serial.print(freeMemory());
        Serial.println(" bytes\n");

#ifdef WDT
        interrupted = false;
#endif
    }

    // Check at roughly 5 second intervals
    delay(4000);

    return;
}


/*
** s e n d _ p a c k e t
**
** Transmit a UDP packet.
**
** Returns:     Nothing     Always
*/
static void send_packet(const char *data, byte *dst, unsigned int udpport)
{
    //Serial.println("send_packet()");

    udpclient.beginPacket(dst, udpport);
    udpclient.write((byte *) data, MAGIC);
    udpclient.endPacket();

    return;
}


Go Up