Arduino‎ > ‎

Brewing Arduino


WiFly : Xbee with WiFi using Arduino serial interface

posted Feb 19, 2012, 9:29 PM by Haris Hashim   [ updated Feb 20, 2012, 5:57 AM ]








Introduction

Ever wanted to add WiFi functionality into your project? Looking for flexible solution that can connect to existing WiFi network be it adhoc or infrastructure mode, using WEP, WPA or WPA2 security?

This WiFi module from Roving Network, with the added advantage of XBee form factor, is a good fit to above needs. Easily configured to securely connect to existing WiFi network. Once configured, it will remember the WiFi connection parameters and will connect to the configured WiFi network automatically.

Worthwhile mention is the module built in RTC. Together with its WiFi capability to connect to internet and synchronize with network time server. Thus complementing Arduino missing real time clock functionlaity. Imagine being able to create a data logger that keeps time as well as synchronize accurately recorded log to the cloud!

It works with existing XBee accessory including XBee USB Adapter, XBee Shield and various DFRobot shield that come with XBee support. An inexpensive WiFi addition to those who already invest in XBee hardwares!

 

Configuration

*Notes: This step are for specific hardware bought from H&T online shop. Applying bellow step on different set of hardware are not advisable and may cause damage or bricking the device. Please be careful! 

As in the last XBee article, we are going to configure the module using XBee USB Adapter. However, instead of X-CTU. The software to be used is called Tera Term. The configuration step is more to the tune of sending raw command instead of using GUI as in the case of XBee. However, it is easy and a very informative process.

Requirement

  • XBee USB Adapter
  • WiFly WiFi module in XBee form factor

*Important: Be careful not to insert WiFly module in reverse in to the XBee USB Adapter. Doing so might damage the module.

Steps

  1. Connect XBee USB adapter to your development machine using USB cable and plugged in the Wi Fly module.
  2. It is a good idea to double check the detected comport number in Device Manager. Otherwise, Tera Term is good enough to display list of connected comports.
  3. Open up Tera Term. File >> New Connection or press ALT-N. Choose Serial and the right port to connect to. Press OK to proceed.
    Tera Term connect to ...
  4. Observed that upon power up, red and yellow LED of the Wi Fly module is blinking. Observed also that the just opened serial terminal is reporting unable to connect to the network. This is because Wi Fi network connection parameter is not configured yet. To do this configuration, we need to be in command mode.
    Tera Term unable to connect
  5. Simply type "$$$" character in the terminal window to enter command mode. No need to press ENTER.
  6. Take note that that command mode can be used to set parameters as well as query a lot of information. Just for kicks, Try get wlan and get ip to see the parameters that we are going to change shortly.
  7. To set WiFi connection using WPA2  issue the following command. Take note that for WPA2, only AES encryption setting is supported on the router.
    • set wlan auth 4
    • set wlan ssid <SSID to connect>
    • set wlan phrase <security key/password>
    • set wlan join 1
    • set wlan channel 0
    • set ip dhcp 1
      WiFi connection configuration
  8. Execute command to save above configuration. Otherwise, the setting will be gone upon power lost. After that reboot.
    • save
    • reboot
      Save &amp; Reboot
  9. The module will than restart and establish WiFi connection with the WiFi router. Note the IP address as we will need it in the next steps.
  10. Development machine must be connected to the same WiFi router to test. Open up windows shell and ping ip address from previous step to verify.
    Ping in command prompt
  11. To demonstrate that the module is now connected to WiFi network, telnet to the IP address. Either using windows shell or Tera Term. When telnet is  successfully   connected, *HELLO* will be displayed. Whatever typed in the telnet terminal will show in serial terminal window used during above configuration steps. We are done with configuration!
    Telnet Test

To The Codes!

As usual, here is a very simple test code for Arduino. The codes it self  is based on SerialCallResponse sample code (Arduino IDE >> File >> Examples >> Communication >> SerialCallResponse). 

During configuration step, we have seen how the WiFly module can be accessed using telnet over WiFi network. We are just going to extend this functionality by having Arduino monitor input sent through telnet session for ON or OFF command set. In a way, it is a demonstration of turning LED over telnet!

Being base on XBee means that communication between Arduino and the WiFly module is serial. I.e. whatever written to Arduino RX pin will be received by the module TX pin and vice versa for the module TX pin and Arduino RX pin. 

The beauty of using shield is that hardware is abstracted. Just plugged in WiFly module on top of a shield with XBee connector and stack the shield on top of an Arduino micro controller board. No need to worry about what RX pin connected what else TX pin :D. It is good to know that the code will just work! Perhaps one day we will delve deeper into this hardware complexity. Definitely that day is not today.

Here is the hardware requirement, or at least what used for this particular coding activity.

Requirement

  • An Arduino micro-controller board. Uno R3 will do nicely.
  • DFRobot IO Expansion Shield just to use something that is lying around and available to me. DFRobot XBee Shield would do it. In fact,  nowadays  DFRobot have a lot of shield with XBee support. Any of this shield will do!
  • WiFly WiFi module in XBee form factor.

Assembly


This is the tricky part. Generally, Arduino board can not be programmed while any XBee module is connected to it. Since the board is sharing serial communication with USB as well as the module. There are ways to work around this, but simplest is to disconnect the wiFly module before uploading the code. The assembly order should be as bellow:
  • Connect Arduino board to your development machine (PC or notebook) using USB cable.
  • Write the codes, compile and upload it to the board.
  • Mount WiFly module on top of the shield and stack the shield on top of Arduino. If needed, power down Arduino board before stacking the shield. Just being careful to avoid accidental shorting whenever board is powered up.
  • If there is need to reprogram the Arduino board, unplug the shield or the WiFly module before reprogramming.


The Code


In summary, the code waits for certain ASCII character which will then turn on or off built in LED on pin 13. DFRobot IO Expansion shield does duplicate the built in LED pin. Otherwise, it will be hard to see the LED on or off status.


Take note of the cmd global variable, basically it keeps track a line of command.



The setup part of the code simply do the necessary to initialize serial communication and set digital pin 13 as output for turning the built in LED on and off. 

The establishContact() function is sort of the place where communication hand shake should happen.


String cmd = "";

void setup()

{

      Serial.begin(9600);

      pinMode(13, OUTPUT);

      establishContact(); 

}



Here we see that establish contact actually is not doing anything much. Remember that this code is running on Arduino, i.e. the Atmega micro controller chip. The mcu simply send ASCII character A through the serial connection until there is a reply from the other side.
The other side, in this case is our WiFly module. Which is relaying the character over WiFi network connection.

void establishContact() {

      while (Serial.available() <= 0) {

            Serial.print('A', BYTE); // send a capital A

            delay(300);

      }

}



The main loop just happen again and again as long as the hardware is running.

So it repetitively wait for a byte of data available to read from the WiFly module serial connection.
When there is such data, it is appended to the cmd global variable, which is a string object. A byte of data is just another way of saying a character. So you can imagine cmd string is being built a character at a time.

As the cmd string is being built, it is being checked whether it is a command or not.



void loop()

{

      if (Serial.available() > 0) {

            // get incoming byte:

            char inByte = Serial.read();

            cmd = cmd + inByte;

            checkCommand();

      }

}




How it is being check is also a simple matter of
  • whether it is a line ended by carriage return and line feed character (CR = \r and LF = \n).
  • whether it is a valid command. Which in this case ON command (turn on LED) and OFF command (turn off LED).
Depending on the command, LED connected to digital pin 13 is going to be turned on or off.


This function simply process commands as it is detected and only once. After that it simply clear the cmd string. So that the global variable will start fresh the next time. To be filled up by another series of character that will build the next command.



void checkCommand(){

      if(cmd.endsWith("\r\n")){

            if (cmd == "ON\r\n"){

                  digitalWrite(13, HIGH);

            }else if (cmd == "OFF\r\n"){

                  digitalWrite(13, LOW);

            }

            cmd="";

      }

}



Arduino R3: Testing Ethernet Shield R3

posted Jan 24, 2012, 4:46 PM by Haris Hashim   [ updated Aug 18, 2012, 5:10 AM ]

Uno Ethernet LED

Introduction

What is the fastest way to test the Ethernet Shield? We will look into that in this article. As well as exploring a little bit of serving HTML and basic information about HTTP protocol.

A Quick Test

For this test, assemble the following
  • Arduino Uno R3
  • Ethernet Shield SD R3
  • PC or notebook with Ethernet port.
  • Ethernet cable
  • USB cable

Troubleshooting

Note that, direct Ethernet connection usually require a loop back Ethernet cable. Have not tested this, but it is possible to connect both PC and Ethernet Shield to a router. Since modern router do not care and auto detect normal cable and loop back cablesdfadf.
  1. The Uno is going to be connected to PC using USB cable. Stack Ethernet Shield on top of Uno.
  2. Connect Ethernet Shield to PC Ethernet port using Ethernet cable. At this point the link is not yet fully operational since IP need to be set on both PC and shield.
  3. Open up Arduino IDE. It is good idea to double check that the board and serial port is correctly set in the Tool menu.
  4. Load webserver sketch example. Navigate the following menu to do so. File>>Examples>>Ethernet>>WebServer
  5. Look for the following code which set the Ethernet Shield IP. Change the IP if required, for instance if there is an IP conflict.
    IPAddress ip(192,168,1, 177);
  6. PC and Ethernet Shield  need to be in the same subnet to be able to communicate. In windows, open up command prompt and use ipconfig command to check this. Note that usually there are more than one network interfaces. Look for "Local Area Connection" or some such. 
  7. As in IP setting for Ethernet, the IP for PC should start with 192.168.1.x. If not, change the IP. In my case it is set to 192.168.1.178.
  8. Double check using ping command in command prompt. Should be able to ping the Ethernet shield IP successfully.
  9. Go back to Arduino IDE where the WebServer example sketch is loaded and upload the sketch.
  10. Open up browser and browse to the Ethernet shield IP. Simply type the IP in browser address box and press enter. You should see the following result.
    analog input 0 is xxx
    analog input 1 is xxx
    analog input 2 is xxx
    analog input 3 is xxx
    analog input 4 is xxx
    analog input 5 is xxx
  11. Read the WebServer sketch code to understand what is going on. In short, the sketch (which is the server) respond to browser (which is the client) HTTP request by sending HTML page. The HTML page content is generated by reading analog input pins value (which are floating values since we do not do anything with it).

Understanding The Code



Peeking at client HTTP Request

HTTP is a topic worth a book by itself. However the following reference should give some basic idea.

To gain better understanding, let's modify the sample code so that we can have a peek into HTTP request sent by browser.

We are going to use Arduino IDE Serial Monitor functionality to achieve this.


void setup()
{
  Serial.begin(9600);   //  1<--- open up serial port connection to PC

//SNIP 

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);   //  2<--- Send every character read to serial port 

//SNIP





  • (1) Add Serial object into the setup part of the code.
  • (2) Send every character read to serial port 
  • Save and upload the code, 
  • After upload is completed open up Serial Monitor window in Arduino IDE (Menu Tools >> Serial Monitor)






  • Refresh browser and observe HTTP request displayed in Serial Monitor. Should see the following screenshot or Serial Monitor window.

Serial


Turning LED On and Off

Assemble the following circuit.

LED Circuit Assembly



Let see interesting part of the code before we move forward.
if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(analogRead(analogChannel));
            client.println("<br />");
          }
   
          break;
        }




  • This is the part where HTML content is dynamically generated and sent back to the client. The first 3 line actually generate http header while the rest of the code loop through all analog port to read their value. This short example does not really observe proper HTML structure (note the missing <header> and <body> tag). But it do the work. This article will continue in that spirit and it is up tp the reader to properly include this in their consideration. 






if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          if (digitalRead(8)){  //  1<-- Display LED status
            client.print(" LED is ON");
          }else{
            client.print(" LED is OFF");
          }
          client.println("<br />");
           
          // 2<-- Create a form
          client.print("<FORM action=\"http://192.168.1.177/\" >");
          client.print("<P> <INPUT type=\"radio\" name=\"status\" value=\"1\">ON");
          client.print("<P> <INPUT type=\"radio\" name=\"status\" value=\"0\">OFF");
          client.print("<P> <INPUT type=\"submit\" value=\"Submit\"> </FORM>");
            
          break;
        }




  • (1) Let's modify the code. Start by totally deleting the for loop. Instead, we will read digital pin 8 and display the value as ON or OFF in the browser.
  • (2) Next add HTML code to generate a form with two  ON/OFF radio input and a submit button.










  • Save and upload the code. Refresh the browser and the result should look as on the right.
Screenshot


void setup()
{
  Serial.begin(9600);       //  open up serial port connection to PC
  pinMode(8, OUTPUT);    //  1<--- Set digital pin 8 as output

//SNIP

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    String buffer = "";  //  2<--- Declare the buffer variable
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        buffer+=c;        //  3<--- Assign to the buffer

//Snip

    if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
          Serial.print(c);   //  Send every character read to serial port 
          buffer="";          //  4<--- Clear the buffer at end of line
        }
        else if (c == '\r') {            
          if(buffer.indexOf("GET /?status=1")>=0)
            digitalWrite(8,HIGH);  // 5<--- Catch ON status and set LED
          
          if(buffer.indexOf("GET /?status=0")>=0)
            digitalWrite(8,LOW);  // 6<--- Catch OFF status and set LED
        }
        else{
          // you've gotten a character on the current line
          currentLineIsBlank = false; 
        }


  • Now we have the user interface needed to turn on and off something. However clicking the submit button will not do anything yet. Code need to be written to process the HTTP request and then set digital pin 8 to high or low. 
  • (1) First of all we need to set digital pin 8 as output pin. Do this in setup.
  • (2) The sample code read a character one by one. We need a buffer to hold this char. So declare the buffer as an empty string.
  • (3) After each character is read, simply append it to the end of string buffer. 
  • (4) Clear the string when there is new line.
  • (5) & (6) This is where we check status input. Simply look for "GET /?status=1" or "GET /?status=0" in each line of HTTP request.
  • Now is a good time to refresh the browser and test the UI again. Selecting the status and clicking submit button should result to LED turning on or off.










Update (20120818):

Chris from Charm City Networks expand on this write up to create an awesome 

Interesting read and a good next step after going through with above tutorial.

Arduino R3 and Shield in Malaysian Shore

posted Jan 2, 2012, 11:08 PM by Haris Hashim   [ updated Jan 5, 2012, 4:03 PM ]

*Update: Both Uno R3 and Ethernet Shield SD R3 are now available from the online shop. A bundle of both or other such promotion should appear shortly. 


I have been holding this two weird (yet no less than the latest) version of Arduino and shield for about a week now. Playing around with it as well as exploring their irregularity.

As distributor, R3 version of Arduino was made known to H&T back in November 2011. But only now I get the chance to play with them. Fear not, might be a bit behind schedule, but perhaps shine more in completeness. Right here there are both Uno R3 and R3 shield. As well as previous version of Uno to compare.

Here are the two new products ... <drum rolls!> ... in boxes


Well, in a box the new Uno (let's just called it Uno R3 henceforth) does not really look any different.


Ethernet SD Shield R3


The surprise is that, the new Ethernet Shield (let's just called it Eth R3 henceforth and be merry ;D) come in a box much like Uno but larger. Which also means you get free stickers, as well as a big thank you note. Buy it together with Uno and you get more of these!

 
Ethernet SD R3 Unboxed

Unboxed
 
Front

The front shows this model is without POE

 
Back

The back shows that this is R3. Click to enlarge and Look for Ethernet R3 at bottom left corner


  

Arduono Uno R3


The Uno R3 packaging is the same. How to tell between R3 and older version?

 
Uno R3 Front

Click to enlarge the picture and count the two additional pin at marked area
 

Uno R3 Back

The glaring different is at the back. Enlarge the picture and look for Uno R3 at top left corner 


Well to be honest, there was never Uno R1. The first Uno is simply just Uno. But that bring up the question about R2. Also, the most curious will even ask why use R as in revision and not V as in version. 

Using revision instead of version implies that small changes is made to the board, hence the R. To continue with this reasoning, R2 is very small revision that does not warrant much celebration. So it was silently release to the market.

But R3 is special, ain't it? Otherwise we will not be reading this article.

Compatibilities


I am going to write more about this in future article. However let's shoot straight directly to the concern of physical compatibilities. After all, there are  additional pins for the new revision. Do remember that R3 applies to Arduino board as well as shields that want to be fully compatible with the R3 revision.

 
Uno R3 with previous shield

CASE1
Uno R3 with non R3 shield, showing 4 female 
header without pins on both side of the board

 
Uno R3 with R3 shield as intended

CASE2
Uno R3 and Eth R3, 
a nice fit
 
Uno R1 and Ethernet SD Shield R3, unintended consequences?

CASE3
Uno R1 with Eth R3,
Oops!

In case 1, it is a given that older revision of shield will not have the additional pins as in R3 revision. The shield will work as intended. Additional note about stacking shield. If there is mix between R3 and non R3 shield, would be good idea to put non R3 shields on top. Since non R3 shields do not pass additional pins interface to top shield.

In case 2, both R3 board and R3 shield as intended. 

In case 3, is what happen when previous revision board is used with an R3 shields. Physically, the extra pins are not really compatible with older revision board.

Not really! That does not looks good, does it? Well, we are in DIY field. As work around, it would be easy to bend the pins using pliers. Or worst case scenario, to cut it as nice as possible.

IMHO, it will slowdown adoption of new R3 shield by third party manufacturer. In the beginning, there will be a lot more of non R3 board compared to the new R3 board. But from the looks of it, Arduino people from Italy are really commited with supplying R3 boards. For instance, it is harder for distributor to get previous revision of Uno at the moment.

So as R3 board become more prevalence in the market. More buyer will prefer shield that follow R3 revision. Hence, third party manufacturer will be happier to make and supply some. Perhaps by then, there will be a better work around at having R3 shield that work with non R3 board?

What is New in R3 Then?


Amazing how we are nearly near the end of the article without any clear mention about what is actually new with Uno R3. Will let a picture do the talking shortly. However, to summarize things up (in textual form that is). Arduino R3 is a minor release. Your existing code and shield should work with it the same as previous revision of Uno. If it does not works, perhaps it is Arduino IDE 1.0 that is the problem? Well that is another story and should be in a different article soon. (Hint: Arduino Uno R3 require Arduino IDE 1.0 to install the hardware driver. If there is code issue or library having compile error, switch back to previous version of IDE and your code will work again!)

There happened to be additional 4 pinout on the board. However 2 of it (SDA and SCL) are duplicate of A4 and A5 pin which also function similarly to facilitate I2C or TWI communication. As  for the other two pinout among the power headers. The first one is not connected at all and simply reserved for future design. The second pinout, labelled as IOREF. Is a little bit vague functionality wise. My understanding is that it will allow future shield to check I/O voltage level of the underlying Arduino board, be it 3.3v or 5v. Definitely this will require further investigation.

With that said, there are other small changes such as using ATMEGA16U instead of ATMEGA8U. But I am getting ahead of my self. Lets bellow graphic do the talking and have fun!



Words From [Home]


Uno R3



Arduino & XBee Quickie

posted Apr 10, 2011, 4:14 AM by Haris Hashim   [ updated Feb 10, 2012, 2:13 AM ]






Introduction


This write up initially is intended as one stop introduction to Arduino and XBee. However it takes so long to cover everything. Thus it is renamed "Arduino XBee Quickie"! Perhaps it will evolve in the future to cover many other things. So like much of other article in this site, it is brewed to change and grow.

Ramblings


Back to the topic. One of the challenge in getting XBee working with Arduino is that it require several component needed to make it work. At minimum, the 3 component is Arduino (Uno or Duemilanove or other compatible board), XBee Shield (I use DFRobot XBee shield) and XBee module (any series 2 will do, series 1 should work, but this article is for series 2).

That should be enough but in truth, it is not! Let me explain. Imagine that you have 2 of everything, including 2 Xbee module. This 2 XBee module need to communicate with each other. The simplest way is to set one as coordinator and the other as end device. Both of the module most likely arrive to your door step pre-configured as coordinator. Additionally they might be configured using Zigbee protocol. As per this tutorial, they need to be configured to ZNet.

To reconfigure (it is actually re-flashing the firmware), one can use Arduino and the XBee shield connected to PC using Arduino USB cable. However this will not work unless either of bellow workaround is done:
  • The MCU chip is unplugged.
  • Put the MCU in perpetual reset state (actual technique is left to reader imagination due to it's dangerousness).
So, there is a need for one component that helps in the configuration step. This fourth component is known as XBee explorer among Sparkfun customer. DFRobot sell a similar product named XBee USB Adapter.

Like the name, XBee USB Adapter connects PC (or notebook) to XBee module through USB. We can then re-configure the module using a program called X-CTU (free program from XBee main manufacturer which is Digi, don't mistake this company with DiGi in Malaysia). But that is not all. Now that we have a way to connect XBee to PC. It can also act as a modem to allow the XBee to communicate with the rest of XBee network!

Remember I did mention about having 2 of everything to make them communicate. So the (previous) setup should be like bellow

   
PC <-- Arduino <-- XBee Shield <-- XBee module (coordinator) <== ==> XBee module (end device) --> XBee Shield --> Arduino

With XBee USB Adapter, we no longger need the additional Arduino XBee shield. So things got simplified as bellow

   
PC <-- XBee USB Adapter <-- XBee module (coordinator) <== ==> XBee module (end device) --> XBee Shield --> Arduino

You would agree that this is one really usefull bugger ;).


XBee Module Configuration Step

*Notes: This step are for specific hardware bought from H&T online shop. Applying bellow step on different set of hardware are not advisable and may cause damage or bricking the device. Please be careful! As rule of thumb, if the device is not identified as "XB24-B", most probably bellow step is not correct for that module.

Bellow step is to configure 2 XBee module. Note that both module must be of the same series (for instance series 2). Please follow the step in exactly order!

  1. Download and install latest X-CTU program from this link --> Digi XCTU Knowledgebase
  2. Plugged in XBee Module into XBee USB Adapter. Make sure it is not reversed. !!!Critical!!! double check to make sure it is not reversed!
  3. Plugged in XBee USB Adapter to the PC using appropriate USB cable. XBee USB Adapter and the XBee module should power up and light the relevant LED.
  4. Go to Device Manager and double check the resulting serial port. If not sure which one, plug and unplug while paying attention to the changes in device manager serial port entry.
  5. Start the X-CTU program. It should start and show the first tab entitle "PC Settings". If not, change to the tab.
  6. In "PC Settings" tab select the correct Com Port. The Baud rate setting is always 9600 *unless it has been changed*. Rest assured that if you don't change it, the default is 9600. No other setting changes is necessary (YMMV).
  7. Click the "Test/Query" button to verify the connection. A message box should pop up. Take note of the XBee module device type in the popped up message box. Mine is "XB24-B". Device type is needed in the next step.
  8. If everything is okay, open up the "Modem Configuration" tab and click the "Read" button. This will read current configuration of the XBee module. Note that this step will also show device type, you can compare with device type noted in previous step. It might take sometime to read current configuration.
  9. We are going to reconfigure the series 2 device as end device and using ZNet 2.5 function set (or protocol). Take caution in this step to select only function set that end with "AT" in the name. Otherwise the module will no longer accept serial command. To the point that is no longer configurable by X-CTU (actually there is a way but it is PITA).
    1. Under "Modem: XBEE" there is a drop down box. Select it according to the device type discovered in step 7.
    2. Under "Function Set" there is a drop down box. Select "ZNET 2.5 ROUTER/END DEVICE AT"
    3. The version should be the latest (or not). You can also click "Download New Versions ..." button to get the latest firmware. However this is not really critical.
    4. Click the "Write" button and wait for the write process to complete successfully.
    5. It is good idea to read the configuration again and double check. However, this is not necessary since successful write implies that the configuration is changed.
  10. Disconnect the XBee USB adapter from PC (to power it off), unplug the module and put it aside. It is a good idea to somehow mark the module in order not to mix them up later.
  11. Done reconfiguring one of the module as end device! One more to go. Which need to be configured as Coordinator. Redo step 2, 3, 6, 7 & 8.
  12. We are going to reconfigure the series 2 device as coordinator and using ZNet 2.5 function set (or protocol). Take caution in this step to select only function set that end with "AT" in the name. Otherwise the module will no longer accept serial command. To the point that is no longer configurable by X-CTU (actually there is a way but it is PITA).
    1. Under "Modem: XBEE" there is a drop down box. Select it according to the device type discovered in step 7.
    2. Under "Function Set" there is a drop down box. Select "ZNET 2.5 COORDINATOR AT"
    3. The version should be the latest (or not). You can also click "Download New Versions ..." button to get the latest firmware. However this is not really critical.
    4. Click the "Write" button and wait for the write process to complete successfully.
    5. It is good idea to read the configuration again and double check. However, this is not necessary since successful write implies that the configuration is changed.
  13. There is no need to unplug the XBee module from the XBee USB Adapter, since it is already configured as coordinator. We are going to use it in the next steps.
* Notes : It is a good idea to check each module PAN ID setting in X-CTU. They should be the same number for both, which is the case by default.

Arduino Interfacing

With above step completed, the other side of the fence is really piece of cake.

I am using DFRobot IO Expansion Shield. But the various XBee Shield including DFRobot XBee Shield should work the same.

Arduino &amp; XBEE

Tips: if there is problem uploading sketch to Arduino, disconnect XBee shield or just the XBee module itself from Arduino board and try to upload the code again.
  1. Let's start with our favourite Arduino board (Duemilanove, Uno or Mega) not connected to any shield. 
  2. Upload the following simple sketch just to say hello to our new toy!

    void setup()  {
      Serial.begin(9600); 
     
    void loop() { 
      Serial.println("Hello XBee!"); 
      delay(1000); 
    }

  3. After sketch is successfully uploaded, unplug the USB cable to power down the board. 
  4. Mount XBee module configured as Router / End Device on the shield and then mount the shield on Arduino. Important! Make sure the xbee module is mounted correctly and not in reversed position.
  5. Power up the board using USB and pay attention on red LED in the vicinity of the XBee module. This LED is steady when the module is not associated with a Coordinator configured module. Since we left the Coordinator configured module connected to the XBee USB Adapter. In a verry short time, this LED will transition from steady to blinking about twice per second.
  6. How to know that the sketch is working? Open up the X-CTU windows used in the configuration steps to view the Terminal tabs. The greeting "Hello XBee" should be seen once every second.
Welcome to the exciting world of wireless communication!

LCD Graphic Shield Plus RTC!

posted Mar 29, 2011, 6:35 AM by Haris Hashim   [ updated Apr 5, 2011, 1:18 AM ]

Read the first part!


Write up coming soon!

The schematic is created using Fritzing. Download Fritzing and open this file to view the circuit.






Codes

// Global area
#include "LCD4884.h"
// Add library & related includes file here
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

const float MULTIPLIER = 0.48828;

// Initialization that run on
// powerup or after reset
void setup(){
 
  // Add code to initialize the RTC lib here
  RTC.stop();
  RTC.set(DS1307_SEC,1);  //set the seconds
  RTC.set(DS1307_MIN,23); //set the minutes
  RTC.set(DS1307_HR,12);  //set the hours
  RTC.set(DS1307_DATE,5); //set the date
  RTC.set(DS1307_MTH,3);  //set the month
  RTC.set(DS1307_YR,9);   //set the year
  RTC.start();
 
  lcd.LCD_init();
  lcd.LCD_clear();
  lcd.LCD_write_string( 8, 0, "Homebrew &", MENU_NORMAL );
  lcd.LCD_write_string( 7, 1, "Technology", MENU_NORMAL );
  lcd.LCD_write_string(14, 2, "presents", MENU_NORMAL );
  lcd.LCD_write_string(16, 3, "Graphic", MENU_NORMAL );
  lcd.LCD_write_string(13, 4, "LCD 4884", MENU_NORMAL );
  lcd.LCD_write_string(16, 5, "Shield", MENU_NORMAL );
 
  lcdBlink(3, 2000);
}

// After setup is completed this part
// of code will repeat until device off
void loop(){
  lcd.LCD_clear();
  int raw = analogRead(2);
  int temp = MULTIPLIER * (float) raw;
  char tempString[6] = "";
  sprintf(tempString,"+%d",temp);
  lcd.LCD_write_string_big(
      15, 1, tempString, MENU_NORMAL);
  lcd.LCD_write_string(
      55, 2, "C", MENU_NORMAL);
 
  // Add code to get current time and display here 
  int hour = RTC.get(DS1307_HR,true);
  int mins = RTC.get(DS1307_MIN,false);
  int second =RTC.get(DS1307_SEC,false);
   
  sprintf(tempString,"%02d:%02d:%02d",
          hour, mins,second);
  lcd.LCD_write_string(0, 0,
          tempString, MENU_NORMAL);
 
  delay(2000);
}

void lcdBlink(int count, int delayMs){
    for(int i=0; i< count; i++){
     lcd.LCD_backlight(1);
     delay(delayMs);
     lcd.LCD_backlight(0);    
     delay(delayMs);
   }
   lcd.LCD_backlight(1);
}

Using Arduino as Oscilloscope - ArduinoScope!

posted Nov 27, 2010, 1:31 AM by Haris Hashim   [ updated Nov 27, 2010, 4:19 AM ]



Introduction


A good friend one time debug circuit and at the same time demo a scope done using Arduino. Interesting stuff! You can visit his blog Arduino For Beginners and get lots of information about Arduino!

Only until today I did give Arduino scope a try. Found that it is PITA to get started due to lack of clear cut documentation. But don't take me wrong. It is fantastic once it get running.

Highly recommended for every home brewers. A multimeter is good to certain extent. It has it advantages. But showing a value in graph form. Current value as well as past value, is not one of them. Having a real oscilloscope easily set us grand amount of dollars. And by that I mean US dollars and not Malaysia dollars (no such thing as Malaysia dollars anyway!).

Anyway, a little bit of background. For those who are already familiar with Arduino. Do you guys know that Arduino is actually based on a platform called Processing? Read wikipedia entry for more info about Processing. In fact running Processing IDE will cause this response of ... "Whoa processing looks like Arduino!". In fact it is the other way around. Arduino looks like processing. Make sense because Arduino is based on processing.

Arduino scope make use of both Arduino and Processing. We will upload a sketch to Arduino board. This cause the board to read voltage value from analog I/0 pin and send it back to PC using serial communication.

On the PC side. We will open up Processing and run a sketch (note that Processing also call it sketch, same as Arduino. Or rather Arduino is using terminology carried over from Processing). The sketch run on PC, listen to the first serial port to accept voltage reading and display it graphically.

That's it in a nutshell. So let see how to set it up.

Tutorial


Step 1


I am assuming that you guys already have Arduino installed :D but no Processing. So head over and download processing.

Extract the downloaded zip file to somewhere convenient. In my case,it is "d:\app\processing".

Run the program. For instance "d:\App\processing-1.2.1\processing.exe".

Upon first run, it will create a folder in user document folder named "Processing". User document folder is "My Documents" folder. You get the drift.

Need to know this "Processing" folder for next step.

Step 2


Just like Arduino (or the other way around, Arduino is like Processing). Processing make use of libraries to make our live easier. Arduinoscope itself is a library. It make use of another library called ControlP5. Which provide graphical UI element for user interface. Need to download it so head to ControlP5 web page and download it

Extract the downloaded zip file into "libraries" folder in "[My Documents]\Processing". Location of [My Documents]\Processing folder is as mentioned in previous step. Make sure that you have "[My Documents]\Processing\libraries\controlP5" folder after executing this step.

Step 3

As mentioned above, Arduinoscope itself is a library. We need to download it too! This is the mind boggling part. But first just head to Arduinoscope usage page.

The page give 2 links for the processing lib and the arduino patchThe first link download the library it self. We will look at the other link in next step.

Anyway, please download the library from Arduinoscope page to get the latest version. After download is complete extract contents to  "[My Documents]\Processing\libraries\arduinoscope". Folder name must be "arduinoscope". This is important, otherwise won't work!

Common pitfall here (and I did this!) is to name the folder following zip file name. Which is "processing-arduinoscope". Won't work!.

Another common pitfall (and I did this too!) is to copy the library to Arduino library folder. Remember that this is processing library and not Arduino library. It will obviously not work. Plus upon starting Arduino IDE. It will complain about library having name with not allowed character until the offending library is deleted or moved somewhere else.

Step 4

Now we need to download the Arduino sketch or called Arduino patch in previous step. Remember that Arduinoscope use both processing Arduino. In this step download the Arduino patch. Basically it is a pde file with exact file name of "arduino-arduinoscope.pde". At the time of writing, the second link for the arduino patch does not work (hint: spelling error involving dash and underscore).

Here is the link that works "arduino-arduinoscope.pde". In the future, might be agood idea to download from Arduinoscope page. In case it is updated or the above error is corrected.

Here is another mind boggling part. What the hell should we do with this file?

First, I would advice to rename the file to "arduinoscope.pde" for no rational reason. Just for kicks ;D

Create a folder named "arduinoscope" in Arduino sketch folder and copy the sketch there. Arduino sketch folder is located in "[My Documents]\Arduino\sketch".

Now it is time to run our beloved Arduino IDE. Then open up the sketch from menu File>Sketchbook>sketch>arduinoscope. Upload this sketch to Arduino compatible board.

Which bring us to another pitfall! The pitfall of not having same name for folder and sketch file. If the file name is "arduinoscope.pde". The folder name must be "arduinoscope". Otherwise won't see the sketch in File>Sketchbook>sketch menu. Apparently can still browse and open using File>Open menu.

At the end of this very long step. Make sure that you have an Arduino board (Duemilanove or Uno or any compatible board) uploaded with the Arduino patch. This board will run and continuously send analog voltage reading to the PC using USB. This reading is going to be read in next step.

Step 5

Back to processing IDE. In the IDE we are going to open up the sketch that is responsible for reading the serial value from first found com port. This value came from Arduino board as described in last step. The sketch will show a graph as what we expect from an oscilloscope.

So where can we find that sketch? One concept learned from last step is that. Sketch file located in sketch folder and is conveniently accessible from  File>Sketchbook>sketch. In the case of processing, this will be "[My Documents]\Processing\sketch".

Another concept that is not immediately clear is that libraries can provide example sketch! Check it out by browsing to "arduinoscope" library folder. Inside that folder there is an "examples" folder with sketches inside. This example sketch is accessible from menu File>Sketchbook>libraries>arduinoscope>examples.

Phew! that is a long one.

So go ahead and open up a sample sketch by doing File>Sketchbook>libraries>arduinoscope>examples>SimpleSerialArduinoscope.

Before running the sketch. Note that in Processing, there is only run button but no upload button. Processing runs sketch in the PC. As opposed to Arduino, which run sketch on a remote Arduino board. Hence the upload button for Arduino and no such button in processing.

Run the sketch! This will open up another window with graphical oscilloscope interface.

Step 6

We have a sketch on the PC showing oscilloscope. On the other end we have Arduino board running. So how do we test?

What happening is that the Arduino board is sampling voltage value on analog I/O pin 1 to 6 in a loop. Since at the moment, nothing is connected to  the pins. The values are sort of zero with a little bit of background noise.

To test, connect 5V pin to analog I/O pin 1. Immediately our Arduinoscope running in PC will show readings in the area of 5v. Disconnect 5V pin and connect it to 3v3 pin. This will cause reading to drop down to 3V3 level.

Weird Stuff

Display on PC show 6 readings possibly for the 6 channel of analog I/O pin. Let say 5V is connected to analog I/O pin 1. All 6 readings show a decreasing value of 5V. Perhaps there is a bug somewhere.

Will try to connect 5V to analog I/O pin 1, 3V3 to analog I/O pin 2 and see what is going on.












Testing Arduino BT

posted Nov 23, 2010, 1:06 AM by Haris Hashim   [ updated Nov 27, 2010, 4:22 AM ]


    Introduction


    Arduino BT is an Arduino board that already have built in Bluetooth module. This simplify hardware interfacing. When it is up and running it simply act as normal Bluetooth device. Pair it with a PC or notebook, and it is ready to talk to Arduino IDE for programming. As simple as that.

     

    There lies the catch. The "When it is up and running part". Arduino BT is using Bluetooth connection. It has no built-in port to accept USB. The catch is that, it is not as easy to power up. Compared to Uno or Duemilanove which is USB powered.

     

    So how do we power it up. Arduino BT does come with +ve and -ve terminal. In this article. I am going to demonstrate how to use this terminal to power up Arduino BT using AA batteries. Test it by uploading LED Blink  sample program and highlight some possible issue and pitfall along the way.

     

    However, please note that this article is not a complete replacement to Arduino BT hardware page. The most important being hardware specification such as maximum voltage. So, do check the page and base your design upon the specification given there.

     

    A good advice at this point is to understand that, unlike other board, Arduino BT maximum voltage is specified as 5.5V.  So it is very critical to be careful with the power up stage. It is a good idea to use multi meter and double check that batteries or adapters +ve and -ve terminal voltage did not exceed 5.5V.

     

    A good point to think about is that power adapter (or wall warts) voltage under load should be lesser than the voltage measured by multi meter on the terminals without any load. But at this moment I'm taking "it is better to be safe than sorry" stance.  Will revisit this in the future. Perhaps continue with another article on powering Arduino BT using power adapter.

     

    In Malaysia, AA battery is commonly rated at 1.5V. Having 2 batteries in series give about 3V. Which is enough voltage to power up the board and within spec. However this say nothing about the amount of charge hold by the battery or how long will it last. So here is our first pitfall of the day. And I am a pitfall magnets.

     

    Personal experience. Run down 6 AA batteries to death in the half day of troubleshooting. The reason being using normal grade batteries! So dear readers, please use  Alkaline batteries. Better yet,  use rechargeable batteries!

     

    With that said, after initial test is done. I did use 4 AA rechargeable batteries in series . Each of the battery rated at 1.2V with 2100mAH charge capacity. Do be careful not to use 4 AA battery with 1.5V rating. That is 6V and possibly may damage the built in and soldered micro controller. Definitely not user replaceable. Unless the user is very skilled in soldering and desoldering surface mount chip with many small pins.


    Tutorial



      

    Step 1

    Assemble the simple circuit. Note that diode is to prevent reverse polarity. Still, be careful not to reverse polarity when connecting the second terminal header to Arduino BT.

     

    At this point we are not using the LED yet. So leave it unconnected.

     

    Good idea to double check the battery voltage using multimeter before going to next step.

     

    Step 2

    Connect the circuit +ve terminal (red wires)  to Arduino +ve terminal. Connect the circuit -ve terminal (black wires)  to Arduino -ve terminal. Battery holder without On/Off switch (as the one used in this article) means that the board will be powered up when both terminal is in contact. Be careful! 


    Step 3

    The board is powered up. There is two on board LED. One is power LED which should be steady on after power is up. The other one is Low Battery LED which will light up when battery is low.

     

    Step 4

    Next we are going to pair Arduino BT with a PC or notebook. Simply do the normal platform specific ways to pair Bluetooth device. I am using a notebook with 64 bit Windows for this test. So in Bluetooth panel, click Add Device and wait for it to detect. Initially it will detect it as Other Device. Select it and click next an follow the instruction. A driver will be automatically installed. Hence forth it will be shown as Arduino BT.

     

    Important: The pairing must be done from PC or Notebook since pass phrase need to be entered. When asked  enter 12345 as the pass phrase.

     

    Step 5

    After driver installation is successful and pairing is done. Verify the COM port number. Simply double click the newly added device  to look at its property page. Select the hardware tab. The comport number should be displayed.

     

    Step 6

    Launch Arduino IDE and open up the Blink  sample. After that, verify or do the following setting:

    • Menu : Tools > Board and choose Arduino BT with the correct microcontroller. In my case it is Arduino BT w/ ATMega328.
    • Menu : Tools > Serial Port and select the correct COM port.

     

    Step7

    Since we already open the Blink sample. Simply upload the code to Arduino BT.

     

    Important: If the upload is not successful with the following error:


avrdude: stk500_getsync(): not in sync: resp=0x00
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

     

    My theory; the error is due to on board Bluetooth module on Arduino BT actively communicate with Arduino microcontroller using RX and TX pin.  Arduino IDE also use this RX/TX as serial port to program the microcontroller chip. Hence the error. Apparently not everyone suffer this problem and base on internet search, some manage to solve it by replacing Bluetooth adapter on the PC/Notebook side.

     

    Fear not! The work around is to press Arduino BT reset button, release it and immediately (within 2 second) press the upload button in the IDE. Works like a charm!

     

    The reason being, boot-loader programmed into the micro controller wait for 5 second for programming serial communication before continuing with other function.

     

    Step 8

    Upload is completed, the board reset itself and is running, but where is the blinking LED!

     

    Don't panic! Unlike Arduino Uno or Duemilanove. Arduino BT does not come with onboard LED connected to digital I/O pin 13.

     

    This is the time to connect LED black wire to GND and yellow wire to pin 13 on the Arduino BT board.

     

    Step 9

    If everything goes well, enjoy the blink!



    Comments





Prototype Shield - Using on Board Bounce Switch and LED

posted Oct 23, 2010, 3:24 AM by Haris Hashim   [ updated Oct 26, 2010, 12:41 AM ]

Prototype Shield is a very nice addition to Arduino shields (or extension board). It is like a blank piece of paper. This shield is sort of a blank shield with lots of hole for wire wrap and even pads for 28 pin DIP chip and 14 pin SOIC chip. Also very useful are trace of GND and VCC that act as rail for both. Love this as it is easy to test circuit using multimeter as shown by image on the right.

It came with mini breadboard that is self adhesive. In case anyone got bored with wire wraps, simply use the breadboard bonded with adhesive on top of the shield or just leave it bouncing around!

As a shield it come with standard shield connector. Mostly I found that it is very useful to use jumper wire on the connector.  Either connect the digital or analog pins to mini breadboard or one of the wire wrap holes on board. 

However do be cautious not to short anything when jumping around with the wires on life board! I believe in sharing common pitfall of electronic with everyone. It happen to me twice! Windows just complains about power surge on the USB port (yikes!) and display popup that advice to unplug the cable,  reconnect then reset the affected USB hub. In one occasion, I have to restart the notebook to get Uno detected as serial port again.

I got one inquiry about how to use the on board bounce switch and LED. The secrete is to know which of the wire wrap hole correspond to the switch and LEDs. Let bellow picture do the talking.


With the above information, a mini breadboard, some jumper wires and a pull-up resistor we get the following work of arts!


Check the following video and source code after it!



Source Code

// This source code start as example code from Arduino
// Original credit goes to  DojoDave modified by Tom Igoe
// Then I did a minimal modification just to make it works 
// with DFRobot Prototype Shield

// constants won't change. They're used here to 
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);    
 
 digitalWrite(ledPin, LOW);   
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == LOW) {     
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
  }
}




LCD Graphic Shield Plus Temperature Sensor!

posted Oct 17, 2010, 8:01 AM by Haris Hashim   [ updated Mar 29, 2011, 7:46 AM ]

This shield is one of the new toy in my recent DFRobot shipment. Being a display shield, it has to be positioned top most. Otherwise, how to see the display? So there is no standard top shield connector provided. Instead, an array of 3 pin male connector can be found on top of the shield. 

Upon closer inspection, this 3 pin connector can be used to connect DFRobot sensors. This is where things get exciting. Anyway, I planned to blog about  the sensors too. Now both LCD Graphic Shield and sensor can be tested and blogged about in one article!

Please note that there are two type of sensor in DFRobot standard sensor set. Analog sensor and digital sensor. Connectors for digital sensor are on top left corner, while for analog sensor are in the bottom right corner of the shield. It is a row of three pins. The first pin are the sensor output, which can be analog or digital. The other two pins are VCC and GND. 

 
The shield on top of Uno

Connector for digital sensor

 
Connector for Analog sensor


It might not be obvious initially, but they both require different type of cable. Due to pin out configuration that switch between VCC and GND. 
  • For Analog sensor, pin 1,2 and 3 are respectively Signal (S), Ground and VCC. 
  • For Digital sensor, the pin 1,2 and 3 are respectively Signal (D), VCC and Ground. 
So a common pitfall (happen to me!) is to use digital cable with analog sensor or vice versa. Which will not work!

Here is pictures of digital and analog cable. Also picture of LM35 Linear Temperature Sensor which is an analog sensor. Hence pictured using analog cable. Click the picture for larger view.


 Left: Analog cable
Right: Digital cable

Analog sensor using analog cable.
 


Setting up the hardware part of this tutorial is as simple as:
  1. Stack the LCD Graphic Shield on top of an Arduino board. In my case I use Uno, the latest basic official Arduino board.
  2. Connect LM35 Linear Temperature Sensor to analog input 5. Make sure pin 1 is S, pin 2 is GND and pin 3 is VCC.
  3. Connect Arduino board to the PC or notebook using USB and un the Arduino development environment. Don't forget to set the appropriate COM port and board type. 
The rest is coding which we will go through in picture tutorial bellow. In the mean time, enjoy this video showing the display output. Help to visualize what is going to happen!



Picture Tutorial




Source Code

// Global area
#include "LCD4884.h"

const float MULTIPLIER = 0.48828;

// Initialization that run on 
// powerup or after reset
void setup(){
  lcd.LCD_init();
  lcd.LCD_clear();
  lcd.LCD_write_string( 8, 0, "Homebrew &", MENU_NORMAL );
  lcd.LCD_write_string( 7, 1, "Technology", MENU_NORMAL );
  lcd.LCD_write_string(14, 2, "presents", MENU_NORMAL );
  lcd.LCD_write_string(16, 3, "Graphic", MENU_NORMAL );
  lcd.LCD_write_string(13, 4, "LCD 4884", MENU_NORMAL );
  lcd.LCD_write_string(16, 5, "Shield", MENU_NORMAL );
  
  lcdBlink(3, 2000);
}

// After setup is completed this part
// of code will repeat until device off
void loop(){
  lcd.LCD_clear();
  int raw = analogRead(2);
  int temp = MULTIPLIER * (float) raw;
  char tempString[6] = "";
  sprintf(tempString,"+%d",temp);
  lcd.LCD_write_string_big(
      15, 1, tempString, MENU_NORMAL);
  lcd.LCD_write_string(
      55, 2, "C", MENU_NORMAL);
  delay(2000);
}

void lcdBlink(int count, int delayMs){
    for(int i=0; i< count; i++){
     lcd.LCD_backlight(1);
     delay(delayMs);
     lcd.LCD_backlight(0);     
     delay(delayMs);
   }
   lcd.LCD_backlight(1);
}

*NOTE* : Stay tuned for the next part. Where we will demonstrate the simple code to bounce the temperature reading around and add RTC chip and turn this temperature display to temperature display plus clock! Here is the next part!



Conversation Element


Basic Tutorial by Beginner : Matrix LED Part 2

posted Oct 8, 2010, 12:08 AM by Haris Hashim   [ updated Oct 20, 2010, 10:07 AM ]



Source Code

const int Row4 = 4;
const int Row5 = 5;
const int Col4 = 10;
const int Col5 = 11;


void setup() {   
  pinMode(Row4, OUTPUT);    
  pinMode(Row5, OUTPUT); 
  pinMode(Col4, OUTPUT); 
  pinMode(Col5, OUTPUT); 
  
  digitalWrite(Row4, HIGH);
  digitalWrite(Row5, HIGH);
  digitalWrite(Col4, LOW);
  digitalWrite(Col5, LOW);
}

int iter = 0;

void loop() {  
  
  iter = iter + 1;
  if (iter >= 50)
    iter = 0;

  int milis = 10 * iter;
  
  digitalWrite(Row4, HIGH);
  digitalWrite(Row5, LOW);
  
  digitalWrite(Col4, LOW);
  digitalWrite(Col5, HIGH);
  
  delay(milis);
  
  digitalWrite(Row4, LOW);
  digitalWrite(Row5, HIGH);
    
  digitalWrite(Col4, HIGH);
  digitalWrite(Col5, LOW);
    
  delay(milis);
}



Conversation Element


1-10 of 16