Dexter Industries WiFi and RS485

This is where you talk about the NXJ hardware related topics such as the brick, sensors, LEGO pieces, etc

Moderators: roger, 99jonathan, imaqine

Dexter Industries WiFi and RS485

Postby christophe.burki » Mon Feb 20, 2012 6:34 pm

Hi,

I have buy a Dexter Industries WiFi sensors and I try to send AT commands to the sensor via RS485 (port 4). The WiFi sensor can be programmed and controlled via AT commands. These commands are used to configure everything from the serial communication protocol between the NXT and the wifi sensor. The baud rate of the WiFi sensor is 9600, 8 bit characters, no parity and 1 stop bit.

I have installed the firmware 0.9.1 version. I try to send commands to the sensor but I do not receive coherent response and I did not understand what I'm doing wrong. Here is a what I am doing.

RS485.hsEnable(9600, 512);
byte[] readBuffer = new byte[512];
int writeBytes = 0;
int readBytes = 0;
byte[] sendBuffer = {'A', 'T', 'E', '0', 0x0d};
writeBytes = RS485.hsWrite(sendBuffer, 0, sendBuffer.length);
readBytes = RS485.hsRead(readBuffer, 0, readBuffer.length);
readString = new String(readBuffer, 0, readBytes);
RS485.hsDisable();

The sensor will normally respond with the number 1 when OK and with the number 0 on ERROR. I never read 0 or 1 and value I read is never the same.Can somebody explain me what I'm doing wrong ? Any help is welcome.

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby gloomyandy » Mon Feb 20, 2012 7:25 pm

Hi,
The read and write calls are none blocking so you need to check the return values to see how much has been read/written. You may need to loop on the read waiting for the device to respond.

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3003
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Dexter Industries WiFi and RS485

Postby christophe.burki » Mon Feb 20, 2012 7:51 pm

Hi,

thanks for your answer. The bytes read is not null. I have added a loop in order to check the number of bytes read but it does not work better. Here is the loop I have added.

while (readBytes < 1) {
readBytes = RS485.hsRead(readBuffer, 0, readBuffer.length);
}

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby christophe.burki » Mon Feb 20, 2012 7:56 pm

Hi,

I have forgot to tell something. After adding the loop, the read bytes is always null (ascii char 0x00) but it is not what I expect to have ("0" or "1").

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby gloomyandy » Mon Feb 20, 2012 8:45 pm

What is the value of readBytes? What is the value if you insert say a 10 second delay between the write and the read loop (to giv the device time to respond). Remember there may be some garbage characters on the connection sent when the sensor starts up and you may be reading that. You may want to read all of the data sent from the device rather than exiting the moment you have read a single byte. I would add code to loop forever in the read loop and print out every byte read...

Good luck

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3003
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Dexter Industries WiFi and RS485

Postby Aswin » Mon Feb 20, 2012 11:08 pm

There was a lengthy post on MindBoards about the sensor. You might find some usefull info in there.
My NXT blog: http://nxttime.wordpress.com/
Aswin
Active User
 
Posts: 122
Joined: Tue Apr 26, 2011 9:18 pm
Location: Netherlands

Re: Dexter Industries WiFi and RS485

Postby christophe.burki » Wed Feb 22, 2012 7:55 am

Hi guys,

thanks for all of you informations. I do not have time yet to test again the wifi sensor. I will try with your proposals and read the mindboards post as soon as possible and I will give you a feddback on my progress.

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby christophe.burki » Fri Feb 24, 2012 9:19 am

Hi guys,

after reading the MindBoards post (thanks Aswin), I finally have successfully sent commands to the WiFi sensor. When the WiFi module is powered on, we need to configure it through AT command. The first command to send is the ATE0 which turn off echo. By default the module has echo on. This first command must be sent byte after byte and the response from the module must be read after each byte. All the following commands can be sent with multiple bytes. Note that each command must be terminated by a carriage return (\r or 0x0d). I have a working code that turn off echo, enable software flow control, connect to a wifi network and get an address by dhcp. The WiFi module can then be pinged.

Timer have been inserted between write and read because some commands take time to complete (association and dhcp negotiation) and in verbose mode (ATV1) you will not get the right response.

As described in the WiFi module documentation, the adapter parameters can be stored and recall as a profile. I do not have tested yet this.

Here is the simple code used to test the WiFi module. Forget the Logger which is used to write to the console.

Code: Select all
public class TestWifi {

   /* ---------------------------------- */
   private final static int BUFFER_LENGTH = 2048;
   private static Logger logger = null;

   
   /* ---------------------------------- */
   /**
    * @param args
    */
   public static void main(String[] args) {
                LCD.clear();
      TestWifi.logger.debug("Starting application");
                new TestWifi().go();
   }

   /* ---------------------------------- */
   public void go() {
      RS485.hsEnable(9600, TestWifi.BUFFER_LENGTH);

      int writeBytes = this.RS485WriteByteByByte("ATE0");
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT&K1", 1000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("ATV1", 1000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT+WM=0", 1000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT+WAUTH=1", 1000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT+WPAPSK=yourssid,yourwifikey", 1000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT+WD", 2000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT+WA=yourssid", 2000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      writeBytes = this.RS485WriteBytes("AT+NDHCP=1", 2000);
      TestWifi.logger.debug("writeBytes=" + writeBytes);
      
      RS485.hsDisable();
   }
   
   /* ---------------------------------- */
   public int RS485WriteByteByByte(String buffer) {
      TestWifi.logger.debug("RS485WriteByteByByte(buffer=" + buffer + ")");

      buffer += "\r";
      int bytesWrited = 0;
      char[] bufferArray = buffer.toCharArray();
      Stopwatch stopWatch = new Stopwatch();
      
      for (int i = 0; i < bufferArray.length; i++) {
         byte[] sendByte = new byte[1];
         byte[] readByte = new byte[1];
         int bytesSent = 0;
         int bytesRead = 0;

         sendByte[0] = (byte)bufferArray[i];
         bytesSent = RS485.hsWrite(sendByte, 0, 1);
         bytesWrited += bytesSent;
//         TestWifi.logger.debug("bytesSent=" + bytesSent);
         stopWatch.reset();
         while (stopWatch.elapsed() < 100);
         while (bytesRead < 1) {
            bytesRead = RS485.hsRead(readByte, 0, 1);
         }
//         TestWifi.logger.debug("bytesRead=" + bytesRead + ", readByte=" + new String(readByte));
      }
      return bytesWrited;
   }
   
   /* ---------------------------------- */
   public int RS485WriteBytes(String buffer, int waitMillis) {
      TestWifi.logger.debug("RS485WriteBuffer(buffer=" + buffer + ", waitMillis=" + waitMillis + ")");
      
      buffer += "\r";
      int bytesWrited = 0;
      int bytesRead = 0;
      byte[] sendBytes = buffer.getBytes();
      byte[] readBytes = new byte[TestWifi.BUFFER_LENGTH];
      Stopwatch stopWatch = new Stopwatch();
      
      bytesWrited = RS485.hsWrite(sendBytes, 0, sendBytes.length);
      TestWifi.logger.debug("bytesWrited=" + bytesWrited);
      stopWatch.reset();
      while (stopWatch.elapsed() < waitMillis);
      while (bytesRead < 1) {
         bytesRead = RS485.hsRead(readBytes, 0, readBytes.length);
      }
      TestWifi.logger.debug("bytesRead=" + bytesRead + ", readBytes=" + new String(readBytes, 0, bytesRead - 1));

      return bytesWrited;
   }   
}


Thanks for all which have helped me to finally find a solution to communicate with the WiFi module.

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby skoehler » Fri Feb 24, 2012 5:28 pm

christophe.burki wrote:Hi guys,

after reading the MindBoards post (thanks Aswin), I finally have successfully sent commands to the WiFi sensor. When the WiFi module is powered on, we need to configure it through AT command. The first command to send is the ATE0 which turn off echo. By default the module has echo on. This first command must be sent byte after byte and the response from the module must be read after each byte. All the following commands can be sent with multiple bytes. Note that each command must be terminated by a carriage return (\r or 0x0d). I have a working code that turn off echo, enable software flow control, connect to a wifi network and get an address by dhcp. The WiFi module can then be pinged.


Why do you enable software flow control?
I know, that every example for the Dexter wifi sensor does this. But none of the examples I found seems to handle XOFF/XON escape sequences. For all I know, the XOFF/XON escape sequences must be handled manually. The firmware (neither leJOS nor the LEGO firmware, I believe) handle the XOFF/XON sequences. Have you implemented any XOFF/XON handling? E.g. the sensor may send XOFF to the NXT, when the NXT is sending data too fast.

Also note, that I strongly doubt that software flow control is suitable for half-duplex rs485. If the wifi sensor ever send an XOFF sequence while the NXT is sending data, there will be a collision on the wire which will result in data loss and/or data corruption.
skoehler
leJOS Team Member
 
Posts: 1104
Joined: Thu Oct 30, 2008 4:54 pm

Re: Dexter Industries WiFi and RS485

Postby jdc2106 » Mon Feb 27, 2012 3:31 pm

First, thanks to Christophe Burki for cracking the code on Lejos and wifi.

Second, I'm sorry that I'm coming late to this conversation. We had developed relatively strong set of examples for RobotC and NXC, but as you found, none of the folks that had volunteered to work on a leJOS were able to figure it out yet.

I've been working on flow control in the C languages for the past few days, trying to get something going. I'm going to continue to work on this a bit and I'll share what I've got once I've got a decent example.

Thanks! John
jdc2106
New User
 
Posts: 3
Joined: Sun Feb 13, 2011 7:16 pm
Location: United States

Re: Dexter Industries WiFi and RS485

Postby christophe.burki » Wed Feb 29, 2012 4:33 pm

Hi skoehler,

thanks for your comment.

Software flow control has been enabled because as you have said it was part of the Dexter Industries example. I did yet not have made any test to communicate with the nxt through wifi. I will try not to enable software flow control for my future experience of the wifi module.

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby christophe.burki » Wed Feb 29, 2012 4:49 pm

Hi jdc2106,

I will be very interested about your example when you have something to share.

I'm currently trying to have some communications between the NXT and a PC with the Wifi module. I will share with pleasure all of my works on the Wifi module. Perhaps this will be useful to provide a usable module for lejos but for now it's a bit of discovery. I did not yet claim to be able to provide a complete module.

Best regards,
Christophe
christophe.burki
New User
 
Posts: 7
Joined: Mon Feb 20, 2012 11:32 am
Location: Switzerland

Re: Dexter Industries WiFi and RS485

Postby skoehler » Wed Feb 29, 2012 5:10 pm

christophe.burki wrote:Hi skoehler,

thanks for your comment.

Software flow control has been enabled because as you have said it was part of the Dexter Industries example. I did yet not have made any test to communicate with the nxt through wifi. I will try not to enable software flow control for my future experience of the wifi module.


Flow control is important for many scenaros. In others, it is completely useless. Depending on your tests and the protocol you designed on top of TCP/IP, you won't even notice the difference of software control being enabled or disabled.
skoehler
leJOS Team Member
 
Posts: 1104
Joined: Thu Oct 30, 2008 4:54 pm

Re: Dexter Industries WiFi and RS485

Postby jdc2106 » Thu Mar 01, 2012 2:01 am

Thanks everyone! I have two points to share here:
- First, I have some code for software flow control. The flow control should cut down on 75% of collisions on the RS-485 line. The most likely scenario for a collision is something along these lines: the module is working as a TCP server or HTTP server and is sending information to a CID. While sending information, the module receives information back, and tries to send that information to the NXT, while the NXT is sending information to the module. I think that's the most likely collision scenario; there's always the possibility that a response comes to the module at exactly the same time as a signal is going out to the module, and to handle that, I think you would need hardware control (someone correct me if I'm wrong). Anyways, I have some crude code in NXC (I have it in RobotC as well if anyone's interested) that turns the flow on and off. Putting this around a transmission or reception protocol would be the next step and I'm working on working this example into the code we have already.

- Second, Matt Allen has shared some great examples in NXC for making, saving, and loading profiles. These are in our NXC download on our page if you're interested:
http://www.dexterindustries.com/files/DIWIFI_NXC.zip

Code: Select all
/*
*  www.dexterindustries.com
*  www.dexterindustries.com/wifi.html
*  You may use this code as you wish, provided you give credit where it's due.
*
*  This is a program to demonstrate the DIWIFI lib, by connecting to a WPA protected WIFI network.
*  see more about the Wifi Sensor at www.dexterindustries.com/wifi.html
*
*  TO RUN THIS SOFTWARE YOU MUST USE THE FOLLOWING CONFIGURATION:
*  FIRMWARE: lms_arm_nbcnxc_132_20120205_1737.rfw OR LATER
*  BRICX COMMAND CENTER:  version 3.3.8.10 OR LATER
*  THE LATEST VERSIONS CAN BE FOUND HERE:  http://bricxcc.sourceforge.net/test_releases/
*/

#include "DIWIFI lib.nxc"

task main(){
     ClearScreen();
     TextOut(0, LCD_LINE1, "Test Flow");
     // To test flow control:
     // First call network info.
     // Immediately send XOFF
     // Wait for 10 seconds.
     // Clear buffer.
     // Send XON.
     
     char buffer[256];
     DIWIFI_Echo_Off();
     RS485Read(buffer);
     string sbuffer = ByteArrayToStr(buffer);
     TextOut(0, LCD_LINE2, sbuffer);
     
     byte array_out[] = {'a','t','&','k','1',13};
     RS485Write(array_out);
     Wait(1000);

     RS485Read(buffer);
     sbuffer = ByteArrayToStr(buffer);
     TextOut(0, LCD_LINE4, sbuffer);

     Wait(3000);
     
     ClearScreen();
     DIWIFI_Clear_Read_Buffer_HS();

   // TURN OFF FLOW CONTROL
     byte xoff[] = {0x1B, 0x13};     // XOFF
     byte ex_proc[] = {0x1B, 0x45, 0x0D};
     RS485Write(xoff);               // XOFF
     Wait(500);
     RS485Write(ex_proc);
     Wait(500);

   // CHECK BUFFER FOR ANY CHARACTERS
     TextOut(0, LCD_LINE1, "Buf: ");
     NumOut(50, LCD_LINE1, RS485DataAvailable());
     PlaySound(SOUND_DOUBLE_BEEP);
     RS485Read(buffer);
     sbuffer = ByteArrayToStr(buffer);
     TextOut(0, LCD_LINE2, sbuffer);

// TRY NOW FOR A RESPONSE.  SAY SOMETHING.

     //byte plusplus[] = {'+','+','+'};
     //RS485Write(0x0D);
     //Wait(500);
     RS485Write(array_out);          // Seem to need this as a dummy fire.  The first 22 characters are an error message related.  Afterwards, you get ok's.
     Wait(250);
     RS485Write(array_out);
     Wait(250);

// CHECK FOR A RESPONSE.  ANY RESPONSE.
     TextOut(0, LCD_LINE3, "Buf: ");
     NumOut(50, LCD_LINE3, RS485DataAvailable());
     PlaySound(SOUND_DOUBLE_BEEP);
     
     RS485Read(buffer);
     sbuffer = ByteArrayToStr(buffer);
     TextOut(0, LCD_LINE4, sbuffer);

// TURN FLOW CONTROL BACK ON
     // byte xon[] = {0x11, 0x0D};
     byte xon[] = {0x1B, 0x11};     // <ESC> Q
     RS485Write(xon);
     Wait(500);
     RS485Write(ex_proc);
     Wait(500);

// READ THE BUFFER RESPONSE
     TextOut(0, LCD_LINE5, "Buf: ");
     NumOut(50, LCD_LINE5, RS485DataAvailable());
     PlaySound(SOUND_DOUBLE_BEEP);

     int buffsize = RS485DataAvailable();
     RS485Read(buffer);
     sbuffer = ByteArrayToStr(buffer);
     TextOut(0, LCD_LINE6, sbuffer);
     TextOut(0, LCD_LINE7, SubStr(sbuffer, 17, 34));
     
     Wait(10000);
}
jdc2106
New User
 
Posts: 3
Joined: Sun Feb 13, 2011 7:16 pm
Location: United States

Re: Dexter Industries WiFi and RS485

Postby mattallen37 » Thu Mar 01, 2012 3:13 am

jdc2106 wrote:...there's always the possibility that a response comes to the module at exactly the same time as a signal is going out to the module, and to handle that, I think you would need hardware control (someone correct me if I'm wrong).

Without programming the serial handler on the Wifi module, yes, you would need HW flow control to totally eliminate collisions. Either that, or a full-duplex UART line between the NXT and the Wifi module.

Actually, I saw recently that it should be possible to re-program one of the ARM cores in the Wifi module used for the DIWIFI. Apparently it can be programmed to use UART, SPI, or I2C. That means that in theory, you could re-program it to only transmit a message upon receiving a request over RS485 (a master-slave relationship). That should totally eliminate the problem... at the cost of a new version of the DIWIFI (since the programming pins are not broken out on the current HW version).
Matt
mattallen37
Novice
 
Posts: 28
Joined: Thu Mar 03, 2011 7:45 am

Next

Return to NXJ Hardware

Who is online

Users browsing this forum: No registered users and 1 guest

more stuff