Data exchange from spider to arduino

I would like to generate instructions on a spider which then are transfers to a arduino one and executed on the arduino. What would be the best way to connect the two?

Like I recommended in the last post, serial would be my pick.

Welcome to the community.

It depends on what you mean by “instructions” too. Worth looking at state-machine patterns on the netmf side, depending on the strictness of your needs.

Serial is the common denominator and a relatively easy way to transfer data from one device to another. You can use ASCII which makes debugging easy too, or you can go to a binary transfer to save bits. The only potential challenge you might have (or at least have to think about) is that many true arduinos run at 5v TTL level and the Spider is 3v3 TTL which you might want to use a level shifter between the two to make sure you don’t risk damage (but for a serial port only, you should be OK).

the usage pattern would be that the spider reacts to surroundings and generates instructions like
goto x1,y1
goto x2,y2
goto x3,y3
goto z
pause

Which will get send to the arduino. The arduino executes the instructions and after completing the arduino will send a message to the spider that it is waiting for more instructions, which on that signal the spider will send.

The time taken to calculate new instructions would be nice if shorter than the time taken to execute.
The time taken to send new instructions should be as short as possible.

Here is a concern I have about serial communication: the baudrate is 2400? Are there faster ways of cummunication? USB? TCP/IP (cross?)?

What alternatives do I have?

Serial will happily go up to 1M baud

@ Chakotay -
The time taken to send new instructions should be as short as possible

Serial Handshake CTS/RTS

I am sorry, new to this. Willgeorge, Could you please elaborate on your remark? Right now it does not make much sense to me.

@ willgeorge - I had bad experiences with hardware handshaking in 4.2, if the host app is not responding the complete netmf app would freeze. Could be my app but I abandon the hardware handshaking at that point just because 1 interface could lock up the complete application.

Sorry about the Deleted Post…
I tried to enter sample code but it was not showing what I pasted. (Not even close to it?). I have no idea why.
I will try again and hope for the best.

hardware handshaking in 4.2…

Sorry for the delay. Storms around here and loosing power to the house (off and on) so I turned off my electronic devices.
Can’t say much about 4.2 because I have been using 4.3 since its release. However, I do not recall any serious problems when I was using 4.2.

I use serial often and it is reliable for what I do. (I do not write for commercial use so I can live with a hiccup once in awhile).

What caught my eye was that communication is between two devices that you have control of and not some device you may not know all the details about. It may be a factor if you are using multiple serial ports but I almost always use only one. On a rare occasion I have used two ports without problems also.

As to the hardware… I just use the Extender Module connected to the socket I want. In my case, it is usually Socket 4 on my Raptor (COM2).
I use twisted pairs of wire for Power, TX/RX and RTS/CTS between devices. I also define my own pin usage.

To test RTS and CTS I use a 10K pull up resistor to 3.3 volt and connect it to a interrupt port for each. Not normally needed but it helps if you need to know the current state of the signal. (Used sort of like a Logic Probe)

A rough example of how I define the pins follows. The example is some rough code I was using playing with a ALCAM module.



static InterruptPort LDR0;
static InterruptPort ICheck;
SerialPort UART;
Gadgeteer.Socket socket;

//Pin6 PA2 RTS
private Gadgeteer.SocketInterfaces.DigitalOutput _rts;
//Pin7 PA3 CTS (Currently not used other than setting default false)
private Gadgeteer.SocketInterfaces.DigitalOutput _cts;

void ProgramStarted()
{
            button18.ButtonPressed += button18_ButtonPressed;
            
            //Reset Serial port
            LDR0 = new InterruptPort((Cpu.Pin)24, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh);
            //Interrupt handler
            LDR0.OnInterrupt += new NativeEventHandler(LDR0_OnInterrupt);

            //Get a specific pin to use. Use socket 4 pin 3. (A InterruptPort using iPin)            
            Cpu.Pin Ipin = GT.Socket.GetSocket(4, true, null, null).CpuPins[3];

            //Code by Jay Jay
            var mySocket = Socket.GetSocket(4, true, null, null);
            for (var i = 1; i < 10; i++)
            {
                Debug.Print("Socket Number= " + mySocket.Name + " has Socket Pin=" + i + " with assigned CPU PIN=" + mySocket.CpuPins[i].ToString());
            }
            /* Above Returns:
                Socket Number= 4 has Socket Pin=1 with assigned CPU PIN=-1  //Vcc
                Socket Number= 4 has Socket Pin=2 with assigned CPU PIN=-1  //+5
                Socket Number= 4 has Socket Pin=3 with assigned CPU PIN=27  //PA27
                Socket Number= 4 has Socket Pin=4 with assigned CPU PIN=0   //PA0 TX
                Socket Number= 4 has Socket Pin=5 with assigned CPU PIN=1   //PA1 RX
                Socket Number= 4 has Socket Pin=6 with assigned CPU PIN=2   //PA2 RTS
                Socket Number= 4 has Socket Pin=7 with assigned CPU PIN=3   //PA3 CTS
                Socket Number= 4 has Socket Pin=8 with assigned CPU PIN=30  //PA30 I2C/SDA
                Socket Number= 4 has Socket Pin=9 with assigned CPU PIN=31  //I2C/SCL
            */

            ICheck = new InterruptPort(Ipin, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth); //CPU PA27
            ICheck.OnInterrupt += new NativeEventHandler(ICheck_InterruptEdgeBoth);

            //Raptor socket used
            socket = GT.Socket.GetSocket(4, true, null, null);

            //Pin3 PA27
            socket.ReservePin(Gadgeteer.Socket.Pin.Three, null);

            //Pin4 PA0 TX
            socket.ReservePin(Gadgeteer.Socket.Pin.Four, null);

            //Pin5 PA1 RX
            socket.ReservePin(Gadgeteer.Socket.Pin.Five, null);

            //Pin6 PA2 RTS (Set default)
            socket.ReservePin(Gadgeteer.Socket.Pin.Six, null);
            _rts = GTI.DigitalOutputFactory.Create(socket, GT.Socket.Pin.Six, true, null);

            //Pin7 PA3 CTS (Set default)
            socket.ReservePin(Gadgeteer.Socket.Pin.Seven, null);
            _cts = GTI.DigitalOutputFactory.Create(socket, GT.Socket.Pin.Seven, false, null); 
}

 //I never receive a event for CTS
 void ICheck_InterruptEdgeBoth(uint data1, uint data2, DateTime time)
 {
            //Test for interrupt
            if (data2 == 1)
            {
                Debug.Print("OnInterrupt HIGH event");
            }
            if (data2 == 0)
            {
                Debug.Print("OnInterrupt LOW event");
            }
}
//      

void button18_ButtonPressed(GMG.Button sender, GMG.Button.ButtonState state)
{
    Thread.Sleep(200);
    BeginSerial();
}
//

int read_count = 0;
byte[] tx_data = new byte[128];
byte[] rx_data = new byte[128];
        
string s = string.Empty;
string writetext = string.Empty;
string readtext = string.Empty;

/*
        check the status on these lines before sending the data.
        If the CTS line is high - Only then the data is sent.
        When the device or host is ready to receive data, it asserts RTS line high (1)
        
        RTS_Pin = new outputPort ((Cpu.Pin) GHI.Pins.EMX.IO31, true); //Raptor GT.Socket.Pin.Six
        RTS_Pin.Write (true); // true -> raise RTS, false -> drop RTS
        So, the sequence would be:
        o Raise RTS
        o Write () buffer on serial port
        o Flush () buffer on serial port (waits for last bit to exit)
        o Lower RTS
        o Wait for bytes to be received
        o Pull RTS back to high.
*/

/Test
void BeginSerial()
{
    //K socket (serial + handshaking) - Socket 4 IKU X
    //Pin 1  Pin 2  Pin 3  Pin 4   Pin 5   Pin 6  Pin 7  Pin 8  Pin 9  Pin 10 
    //+3.3V  +5V    GPIO!  TX (G)  RX (G)  RTS    CTS    [UN]   [UN]   GND 

    if (UART == null)
    {
        UART = new SerialPort("COM2", 115200); //Raptor socket 4
        UART.Handshake = Handshake.None;  //Exception if not None
        UART.DataReceived += UART_DataReceived;
        UART.ErrorReceived += UART_ErrorReceived;

        string portNname = UART.PortName; //If wanted

        UART.DiscardInBuffer();
        UART.DiscardOutBuffer();
        UART.Open();

        //Flush data
        UART.Flush();
    }
}
//

void UART_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
    Debug.Print("UART ERROR!"); //For now only
}
//

void UART_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        //Flush data
        UART.Flush();
        //Try to read ALCAM response
        read_count = UART.Read(rx_data, 0, rx_data.Length);

        string s = string.Empty;
        char[] fromByteArray = System.Text.Encoding.UTF8.GetChars(rx_data, 0, read_count);
        readtext = new string(fromByteArray);
        Thread.Sleep(100);

        //Example response for (V Get Version Number of Firmware) is:  "v1.0.1\n!00\n"

        Debug.Print("UART response:  " + readtext + " Data length: " + read_count.ToString());

        if (read_count == 4) //Is error
        {
            if (readtext == "!00\n") //Is OK
            {
                Debug.Print("Response (!00 is SUCCESS)");
                return;
            }
            else
            {
                Debug.Print("Response ERROR! " + readtext);
            }
        }
    }
    catch (Exception ioe)
    {
        Debug.Print(ioe.Message);
    }
}
//

//Test
void LDR0_OnInterrupt(uint port, uint state, DateTime time)
{
    Thread.Sleep(300); 

    if(UART != null && UART.IsOpen)
    {
        byte[] b = null;

        //Use only one! - Test

        //Debug.Print("Command Write: (V) Get Version Number of Firmware."); //worked
        //b = System.Text.Encoding.UTF8.GetBytes("V\n");

        //Debug.Print("Command Write: (J) Read Status Register and Configurations."); //worked
        //b = System.Text.Encoding.UTF8.GetBytes("J\n");

        //Debug.Print("Command Write: (K S) Get Available space on SD card."); //worked
        //b = System.Text.Encoding.UTF8.GetBytes("K S\n");

        //Debug.Print("Command Write: (K U) Get Available space on USB storage."); //No device for now
        //b = System.Text.Encoding.UTF8.GetBytes("K U\n");

        //Debug.Print("Command Write: (I C) Initialize the camera."); //worked
        //b = System.Text.Encoding.UTF8.GetBytes("I C\n");

        Debug.Print("Command Write: (I S) Initialize the SD.");
        b = System.Text.Encoding.UTF8.GetBytes("I S\n");

        UART.Write(b, 0, b.Length);
        //Flush data
        UART.Flush();
        _rts.Write(false);
    }
}
//