Showing posts with label example. Show all posts
Showing posts with label example. Show all posts

Thursday, April 18, 2013

Raspberry Pi, Unipolar Stepper motors, ULN2003 Darlington Pairs, USB Gamepad, Python

For the Raspberry Jam on Sunday I want to bring something that moved and was also interested in getting stepper motors to work with the Raspberry Pi so I decided to build a vehicle using stepper motors to drive the wheels (very slowly) and control it with a USB Gamepad/Joystick

The first thing I had to do was to sort out the sequence of pulses for the Stepper Motors. I did this originally with an Arduino Uno as I wanted to remove as many opportunities for human error as possible and since this would be the first time I would user stepper motors with the Raspberry I thought it best to begin with a platform where I was use to doing I/O.

To operate a stepper motor you send signals to the 4 lines in a set sequence.
For the motors I purchased are 28BYJ48 DC 5V and their sequence is. Yours may be different.

        Line1 Line2 Line3 Line4
Step 1    0     0     1     1  
Step 2    1     0     0     1  
Step 3    1     1     0     0  
Step 4    0     1     1     0  

To get the motor to go in reverse you just run this sequence in reverse order.
Also, strangely if you are doing this using an Arduino the stepper library worked first time for me even though  the sequence is different. But when I tried a second, third or more times it failed unless I changed the sequence.  See here for the details on the sequence in the Arduino Stepper Motor library: http://www.tigoe.net/pcomp/code/circuits/motors/stepper-motors/
This post also has a lot of useful information on stepper motors generally

The first thing that I discovered was that the stepper motors and driver board that was a ULN2003 and some indicator LEDS with the right connector for the motors I bought (Amazon UK / Amazon US - these are available cheaper on eBay) had a slightly different pulse sequence than the examples I found so once I figured that out the motors turned clockwise and anti-clockwise as I expected.

All good, motors and driver board working as expected.

Next to get it wired up to the Raspberry Pi.





Here is an layout using a breadboard and a couple of UNL2003 Darlington Pair ICs. These are the same ICs as on the board so the wiring is the same. The board just makes it a lot easier.

NOTE: I used Fritzing to make the layout and it shows the motor as having 6 wires. There are 6 terminals on  unipolar stepper motor, but the model I bought had the two power lines tied together so only came out to a single wire.  Depending on the unipolar motor you have it may have 5 or 6 wires.



With all the wiring done next it was onto the code.

As I said above the goal was to get the motors controlled by a USB gamepad. The gamepad I used is a Saitek P380 (Amazon UK / Amazon US). I bought mine in PC World for about £10.00 For this I decided to use Python as learning to code properly in Python is one of my 2013 resolutions. Also, Python has a nice library in Raspbian for the GPIO pins and I knew that Pygame which works with Python 2.6x had the ability to read USB gamepads.

After figuring out all the mad stuff to do with getting the motors to work on the Arduino I was delighted that using Python and the GPIO library I got the motor to spin with no real problems.

After a bit of hunting on the Internet I got the code to read the USB gamepad and depending on how you push/pull the analog sticks the motors turned.  Effectively allowing you to drive the vehicle like a tank with independent control for both wheels.

Here is the code I used. It is very simplistic as my hope is that it will be easily understandable by others so it can form the basis of something more interesting. I would expect with a bit of effort even I could reduce the code to about a 3rd of its current size and someone who can code properly could get it even shorter. But for this exercise I wanted to literally show every step in the sequence so it is easy to read, easy to understand and east to adapt.


#!/usr/bin/env python

import os, sys, pygame 
from pygame import locals
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.cleanup()

# set the delay between steps
stepDelay = 0.002

# set up motor 1
GPIO.setup(8, GPIO.OUT)
GPIO.setup(16, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)

GPIO.output(8, GPIO.LOW)
GPIO.output(16, GPIO.LOW)
GPIO.output(18, GPIO.LOW)
GPIO.output(22, GPIO.LOW)

# set up motor 2
GPIO.setup(11, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)

GPIO.output(11, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(15, GPIO.HIGH)
GPIO.output(21, GPIO.HIGH)


os.environ["SDL_VIDEODRIVER"] = "dummy"
pygame.init()

pygame.joystick.init() # main joystick device system

deadZone = 0.6 # make a wide deadzone
m1 = 0 # motor 1 (1 = forward / 2 = backwards)
m2 = 0 # motor 2 (1 = forward / 2 = backwards)
try:
   j = pygame.joystick.Joystick(0) # create a joystick instance
   j.init() # init instance
   print 'Enabled joystick: ' + j.get_name()
except pygame.error:
   print 'no joystick found.'


while 1:
   for e in pygame.event.get(): # iterate over event stack
      if e.type == pygame.locals.JOYAXISMOTION: # Read Analog Joystick Axis
         x1 , y1 = j.get_axis(0), j.get_axis(1) # Left Stick
         y2 , x2 = j.get_axis(2), j.get_axis(3) # Right Stick

         print x1
         print y1
         print x2
         print y2

         if x1 < -1 * deadZone:
             print 'Left Joystick 1'

         if x1 > deadZone:
             print 'Right Joystick 1'

         if y1 <= deadZone and y1 >= -1 * deadZone:
    m1 = 0 # Dont go forward or backwards

         if y1 < -1 * deadZone:
             print 'Up Joystick 1'
             m1 = 1 # go forward
             print m1
             
         if y1 > deadZone:
             print 'Down Joystick 1'
             m1 = 2 # go forward
             print m1

         if y2 <= deadZone and y2 >= -1 * deadZone:
    m2 = 0 # Dont go forward or backwards
              
         if y2 < -1 * deadZone:
             print 'Up Joystick 2'
             m2 = 1

         if y2 > deadZone:
             print 'Down Joystick 2'
             m2 = 2

         if x2 < -1 * deadZone:
            print 'Left Joystick 2'

         if x2 > deadZone:
            print 'Right Joystick 2'

         
   if m1 == 1: # motor 1 go forward
# step 1 motor 1
      GPIO.output(8,GPIO.LOW)
      GPIO.output(16,GPIO.LOW)
      GPIO.output(18,GPIO.HIGH)
      GPIO.output(22,GPIO.HIGH)

   if m2 == 1: # motor 2 go forward
# step 1 motor 2
      GPIO.output(11,GPIO.LOW)
      GPIO.output(13,GPIO.LOW)
      GPIO.output(15,GPIO.HIGH)
      GPIO.output(21,GPIO.HIGH)

   time.sleep(stepDelay)



   if m1 == 1: # motor 1 go forward
# step 2 motor 1
      GPIO.output(8,GPIO.HIGH)
      GPIO.output(16,GPIO.LOW)
      GPIO.output(18,GPIO.LOW)
      GPIO.output(22,GPIO.HIGH)

   if m2 == 1: # motor 2 go forward
# step 2 motor 2
      GPIO.output(11,GPIO.HIGH)
      GPIO.output(13,GPIO.LOW)
      GPIO.output(15,GPIO.LOW)
      GPIO.output(21,GPIO.HIGH)

   time.sleep(stepDelay)

   if m1 == 1: # motor 1 go forward
# step 3 motor 1
      GPIO.output(8,GPIO.HIGH)
      GPIO.output(16,GPIO.HIGH)
      GPIO.output(18,GPIO.LOW)
      GPIO.output(22,GPIO.LOW)

   if m2 == 1: # motor 2 go forward
# step 3 motor 2
      GPIO.output(11,GPIO.HIGH)
      GPIO.output(13,GPIO.HIGH)
      GPIO.output(15,GPIO.LOW)
      GPIO.output(21,GPIO.LOW)

   time.sleep(stepDelay)

   if m1 == 1: # motor 1 go forward
# step 4 motor 1
      GPIO.output(8,GPIO.LOW)
      GPIO.output(16,GPIO.HIGH)
      GPIO.output(18,GPIO.HIGH)
      GPIO.output(22,GPIO.LOW)

   if m2 == 1: # motor 2 go forward
# step 4 motor 2
      GPIO.output(11,GPIO.LOW)
      GPIO.output(13,GPIO.HIGH)
      GPIO.output(15,GPIO.HIGH)
      GPIO.output(21,GPIO.LOW)

   time.sleep(stepDelay)

   if m1 == 2: # motor 1 go reverse
# step 4 motor 1
      GPIO.output(8,GPIO.LOW)
      GPIO.output(16,GPIO.HIGH)
      GPIO.output(18,GPIO.HIGH)
      GPIO.output(22,GPIO.LOW)

   if m2 == 2: # motor 2 go reverse
# step 4 motor 2
      GPIO.output(11,GPIO.LOW)
      GPIO.output(13,GPIO.HIGH)
      GPIO.output(15,GPIO.HIGH)
      GPIO.output(21,GPIO.LOW)

   time.sleep(stepDelay)

   if m1 == 2: # motor 1 go reverse
# step 3 motor 1
      GPIO.output(8,GPIO.HIGH)
      GPIO.output(16,GPIO.HIGH)
      GPIO.output(18,GPIO.LOW)
      GPIO.output(22,GPIO.LOW)

   if m2 == 2: # motor 2 go reverse
# step 3 motor 2
      GPIO.output(11,GPIO.HIGH)
      GPIO.output(13,GPIO.HIGH)
      GPIO.output(15,GPIO.LOW)
      GPIO.output(21,GPIO.LOW)

   time.sleep(stepDelay)

   if m1 == 2: # motor 1 go reverse
# step 2 motor 1
      GPIO.output(8,GPIO.HIGH)
      GPIO.output(16,GPIO.LOW)
      GPIO.output(18,GPIO.LOW)
      GPIO.output(22,GPIO.HIGH)

   if m2 == 2: # motor 2 go reverse
# step 2 motor 2
      GPIO.output(11,GPIO.HIGH)
      GPIO.output(13,GPIO.LOW)
      GPIO.output(15,GPIO.LOW)
      GPIO.output(21,GPIO.HIGH)

   time.sleep(stepDelay)

   if m1 == 2: # motor 1 go reverse
# step 1 motor 1
      GPIO.output(8,GPIO.LOW)
      GPIO.output(16,GPIO.LOW)
      GPIO.output(18,GPIO.HIGH)
      GPIO.output(22,GPIO.HIGH)

   if m2 == 2: # motor 2 go reverse
# step 1 motor 2
      GPIO.output(11,GPIO.LOW)
      GPIO.output(13,GPIO.LOW)
      GPIO.output(15,GPIO.HIGH)
      GPIO.output(21,GPIO.HIGH)

   time.sleep(stepDelay)


Once I put together the physical vehicle using cardboard, Nutella jar lids and some glue I tried it out.
It worked. The main thing that would need to be improved is the wheels.
As the Nutella jar lids are light plastic they wobbled a lot causing them to grind on the cardboard chassis. I used some toothpicks to stop the wheels turning in too much and this for the most part stopped the problem.
Here is a short video of it working.


As you can see I definitely won't be racing this bad boy, but it was great to work with stepper motors, python and pygame as well as upgrade some of my cardboard cutting and shaping skills.


Saturday, August 25, 2012

Arduino, Ethernet, Ethercard, XAMPP web server, PHP web page controlling 2 LEDs

[UPDATE 17 Sept 2012 - I have modified the XAMPP webserver code  get the details for the Arduino(s) from a database.  See the updated version here

I tinkered a while back with using a web server to control and Arduino over a serial connection and then I got an ENC28J60.  A really cheap Ethernet socket that can work with the Arduino. It uses the Ethercard community provided library.

My goal was to find a way to turn on and off LEDs which can later become Servos once I've done the hard coding from a web server that then connects to the Arduino over Ethernet.

Using this method the web server and the Arduino don't have to be near each other and even more importantly they don't need to be physically connected.

After a bit of research and trial and error I have something working.
This example presents a simple PHP based web page on the web server with the options to turn on or off 2 LEDs. (sorry for the gaudy colours in the video I thought it would be good to match the LED colours with the menus.

When you click a button on the web page it calls itself with a POST variable set.
The PHP page then interprets this and does an fopen() to the Arduino to do the requested action.

By doing an fopen() the actual connection to the Arduino is not shown on the web page.

The fun with this is that it could be expanded to control more pins easily and also control more than 1 Arduino.



PHP Code on the Server


<!--
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com

This code works with the Ethercard_LED_ONOFF_PHPCall code for Arduino to control Pin2 and Pin4 on
the Arduino using a web server as the interface.
The web page is served with the options and when you click the button it does an fopen in the background
to the Arduino with the relevant command.
By doing this the IP address of the Arduino is not needed and also the commands to control the Arduino is not 
shown publicly when compared to using the Arduino as the web server itself and using a GET REQUEST.

By doing it this way you have more control over the Arduino and the web interface.

NOTE:
As always my code is rough and is designed to get things done rather than beign perfect or pretty.
Use as you wish and let me know your thoughts.

-->

<!-- Start of the HTML -->
<html>
<head>
<title>Click to Turn on or OFF the LED in the background</title>
</head>
<body bgcolor="#FF9933">
<?php

// Check of LED2 is set.  If it is use it
if (isset($_POST["LED2"]))
{
$LED2= $_POST["LED2"];
//echo "<b>$LED2</b>";
}
else
{
$LED2 ="";
}
if ($LED2 == "ON")
{
// Set led2 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED2=ON", "rb");
}
else if ($LED2 == "OFF")
{
// Set led2 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED2=OFF", "rb");
}

// Check of LED4 is set.  If it is use it
if (isset($_POST["LED4"]))
{
$LED4= $_POST["LED4"];
//echo "<b>LED4 is $LED4</b>";
}
else
{
$LED4 ="";
}
if ($LED4 == "ON")
{
// Set led4 ON by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h = @fopen("http://192.168.1.5/?LED4=ON", "rb");
}
else if ($LED4 == "OFF")
{
// Set led4 OFF by calling the Arduino using fopen
//ini_set("allow_url_fopen On", true);
$h= @fopen("http://192.168.1.5/?LED4=OFF", "rb");
}

?>
<!-- LED2 FORM -->
<table>
<tr><td colspan="2"><font size="4" color="yellow">Turn on and off the LED2</font></H4></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED2" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>

<table>
<tr><td colspan="2"><font size="4" color="green">Turn on and off the LED4</font></td></tr>
<tr><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="ON">
<input type="submit" name="submit" value="ON">
</form>
</td><td>
<form action="led2.php" method="post">
<input type="hidden" name="LED4" value="OFF">
<input type="submit" name="submit" value="OFF">
</form>
</td></tr>
</table>


</body>
</html>

Arduino code

/*
Winlkeink
August 2012
For feedback, comments and questions go to winkleink.blogspot.com

Script to allow the controling on the Arduino over Ethernet using an ENC28J60 Ethernet socket and the Ethercard library
Assigning Static IP for the Arduino so I can know exactly which Arduino I am controlling
For this example the request is either http://192.168.1.5/?LED2=ON or http://192.168.1.5/?LED2=OFF
These can be called directly but then the Arduino would have to be the web server and present back the web page
with the option to turn the LED off or ON

For this example I am controlling the Arduino from a webserver on my PC (XAMP) using a PHP script.

*/
// I took took inspiration from the following 2 examples

// The BackSoon example provided with the EtherCard library
// Present a "Will be back soon web page", as stand-in webserver.
// 2011-01-30 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

// Example from the Internet
// https://github.com/lucadentella/enc28j60_tutorial/blob/master/_5_BasicServer/_5_BasicServer.ino
#include <EtherCard.h>

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
// ethernet interface ip address
static byte myip[] = { 192,168,1,5 };
// gateway ip address
static byte gwip[] = { 192,168,1,1 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

// Using a Variable for the Pin, but it is not necessary 
const int ledPin2 = 2;
const int ledPin4 = 4;


// Some stuff for responding to the request
char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

// Small web page to return so the request is completed
char page[] PROGMEM =
"HTTP/1.0 503 Service Unavailable\r\n"
"Content-Type: text/html\r\n"
"Retry-After: 600\r\n"
"\r\n"
"<html>"
  "<head><title>"
    "Arduino 192.168.1.5"
  "</title></head>"
  "<body>"
    "<h3>Arduino 192.168.1.5</h3>"
  "</body>"
"</html>"
;

void setup(){
// Set Pin2 to be an Output
  pinMode(ledPin2, OUTPUT);
// Set Pin4 to be an Output
  pinMode(ledPin4, OUTPUT);

// Scary complex intializing of the EtherCard - I don't understand this stuff (yet0  
  ether.begin(sizeof Ethernet::buffer, mymac);
// Set IP using Static
  ether.staticSetup(myip, gwip);
}

void loop(){
  
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

// IF LED2=ON turn it ON
  if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(ledPin2, HIGH);
    }

// IF LED2=OFF turn it OFF  
    if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2=OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(ledPin2, LOW);
    }

// IF LED4=ON turn it ON
  if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=ON") != 0) {
      Serial.println("Received ON command");
      digitalWrite(ledPin4, HIGH);
    }

// IF LED4=OFF turn it OFF  
    if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4=OFF") != 0) {
      Serial.println("Received OFF command");
      digitalWrite(ledPin4, LOW);
    }

//Return a page so the request is completed.

    memcpy_P(ether.tcpOffset(), page, sizeof page);
    ether.httpServerReply(sizeof page - 1);
  
}

If you want more details on using the ENC28J60 check out my previous post on it.  It gives details on wiring and various libraries for it.







Tuesday, May 15, 2012

Arduino - HC-SR04 ultrasonic distance sensor

Last Christmas as part of my stocking fillers I got an HC-SR04 ultrasonic distance sensor.
Like most of my electronic bits it's a cheap generic device from ebay.  It's a small sensor that is suppose to do the same thing as the Ping sensor but for less money.


I finally unwrapped it and found a library for Arduino IDE 1.0 at HERE.  There is even some sample code to read the HC-SR04 and display the results on an LCD display.


Wiring is really simple
VCC - 5V
GND - GND

Trig - Trigger Pin you define in the code
Echo - Echo Pin defined in the code

Since I don't have an LCD display (yet) I modified the code to use the Serial Monitor as the output.
Code Below:

    #include "Ultrasonic.h"

      int TriggerP = 13; // Trigger Pin for Sensor
      int EchoP = 12; // Echo Pin for Sensor
     
      Ultrasonic ultrasonic(TriggerP,EchoP);   
   
       void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      Serial.print("Distance: ");
      Serial.print(ultrasonic.Ranging(CM)); // Get Range in Centimetres
      Serial.println(" Cm.");
      delay(1000);
      Serial.println("..."); // Next lines.
    }

This worked great up to about 16cm.  But beyond that it started to give me some random numbers greater than 4000, so I'd expect not very robust.

I continued my search and found the following code that doesn't use any library, and this code even does the Serial Monitor as the output so no modification needed.


/*
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12
 More info at: http://goo.gl/kJ8Gl
 */

#define trigPin 12
#define echoPin 13

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  int duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(500);
}

This code performed better, working out to about 24cm.  
While doing my research on using the HC-SR04 I did find a post (somewhere...) stating that when powering from USB the 5V line can be a little bit off so this might be part of my problem.

But, using either method I have a sensor that is good up to 15cm which could be good enough for a small autonimous robot as if I'm within 15 cms I will need to look around for another direction.

NOTE: If you are using a version of the Arduino IDE before 1.0 then at the following LINK you can get the relevant library.  It looks like it's the same as the 1.0 library and has similar performance.

The hunt is on to see if there is a way of getting a reading beyond 24cm that is reliable.

Loving the tinkering.


UPDATE:
I combined some of the code from the Library with the direct code and now it reliably(ish) without detailed testing will work to 70cm.

The modified code is below.


/*
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12
 More info at: http://goo.gl/kJ8Gl
 */

#define trigPin 13
#define echoPin 12

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line

  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(1000); - Removed this line
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(500);
}

Once again, I love this Tinkering.


Tuesday, May 1, 2012

Arduino & TVout Game Columns

After the little bits of coding and small videos that I have posted already I now have a working version of the classic game Columns working on an Arduino using the TVOut Lobrary to drive a composite video display.

I need to do a little cleaning up of the code, but if you want a copy just ask.  Happy to share.

Here's the usual video showing it working.


As promised now that I've tidied up the cdoe a bit here it is.

Update: 6 May 2012: Link to Code
http://dl.dropbox.com/u/9935575/Code/Ardunio_TVOut_Columns.zip


Update 8 May 2012 - Added Breadboard Layout using Fritzing

Thursday, April 26, 2012

Arduino TVOut 3 Blocks Falling


Still working with the Arduino and the TVOut library.
Now I have 3 block falling instead of 1.
Starting to look more like the basics of a game.  A bit more coding to do and maybe some buttons to enable the player to actually control something.







Thursday, April 19, 2012

Prime Numbers

I was watching the video below and I spotted that the Benchmark BM9 is getting Prime Numbers. 

 

This reminded me of a program I wrote in 1986 (20 I'm old years ago) to work out Primes on an Apple ][ in school.
So, I just had to fire up a BASIC interpreter (BASIC-256) to see if I could recreate it again.
Below is the code I did today with loads of REM comments to explain what I did.

REM Printing the Prime numbers up to 10,000 (maxcheck)
REM Winkleink - 2012
REM Just print the 1st 3 Primes
print 1
print 2
print 3
REM x is what we are checking set x to the next biggest odd number
x=5
REM number up to which we will check for primes
maxcheck = 10000
while x < maxcheck
REM Start the checking with 3 as 1 isn't valid and we are only checking odd number
i = 3
REM Set indicator if prime to 1 (means prime)
isprime =1
REM We only have to check odd numbers up to the Square Root of X as any number that will divide into X evenly will be made up of a number below SQR(x) and 1 above SQR(x)
while i <= int(sqr(x))
REM Check not Prime by seeing if there is a remainder if there is no remainder set isprime to 0
if x/i = int(x/i) then isprime=0
REM If not prime then set i to be above the while loop
if isprime = 0 then i= int(sqr(x))
REM Increment i by 2 as only need to divide by odd
i = i +2
endwhile
REM If isprime is still 1 then it is a prime number
if isprime=1 then print x
REM Increment x by 2,again even numbers won't be prime
x = x +2
endwhile

It was great fun to do and really brought back memories of sitting in the computer room in school watching as it slowly printed out the results.  A bit faster today.

And here is a video of it working.


 
As always.  Code is rough and just done for fun.  If you know a better way to calculate primes let me know in the comments.




Saturday, January 14, 2012

Arduino + ENC28J60 Ethernet Module - Part 2

So at the end of my last adventure with the ENC28J60 and my Arduino Uno I got it working with the 0021 IDE  (so I expect it will work with 0022 and 0023 but I have not tested) and the nuelectronics.com library available from here http://www.nuelectronics.com/download/projects/etherShield.zip  using the following wiring to an Uno.

VCC - 3.3V
GND - GND
SCK - Pin 13
SO - Pin 12
SI - Pin 11
CS - Pin 10

After my success with this I thought I'd try it with IDE 1.0 and it failed.  The nuelectronics library for the ENC28J60 does not work (as of writing) with IDE 1.0.

After a little more hunting I found the ethercard library https://github.com/jcw/ethercard that works with IDE 1.0.  I loaded up the backSoon web server sketch that even uses DHCP to get it's IP addess.
FAIL...

I was beaten and abandoned the effort until today.
Well, not really today as between Thursday and today I have been trawling the web to find anything that would help me and I found it.  Not any official update or guide but a post in the forum for the ethercard with the statement:
a new optional 3rd arg to EtherCard.begin() lets you specify the chip select pin (8..10, default is 8)
Wait a second the EtherCard library uses Pin 8 by default for CS.

So, today I setup up the Arduino and ENC28J60 with the following wiring

VCC - 3.3V
GND - GND
SCK - Pin 13
SO - Pin 12
SI - Pin 11
CS - Pin 8

Started IDE 1.0, loaded the backSoon Sketch.
Compiled and ran it.
Checked my routers list of DHCP clients and there was 1 for Arduino-DB witn an IP of 192.168..1.2
Well an IP address has been assigned
Fired up Firefox and went to 192.168.1.2
SUCCESS!!!!!

Now it's all about figuring out all the technical gubbins on the library so I can do my own stuff.
I want to be able to send data to a webserver and also read data from a webserver and do something based on the data.


Not asking too much but at the moment I have no idea how to make the most of the EtherCard library so a bit of Googling and testing required.  This will keep me entertained through the cold winter months...


UPDATE August 2012: OK, maybe the cold winter  months passed before I got back to this.  A bit more fun with the ENC28J60 and using a web server coded in PHP to control it. http://winkleink.blogspot.co.uk/2012/08/arduino-ethernet-ethercard-xamp-web.html

Thursday, January 12, 2012

Arduino + ENC28J60 Ethernet Module

For Christmas I got a small ENC28J60 Ethernet module from eBay in my stocking.
All the advertisers stated it worked with Arduino so I thought let's have a go.

This is a small cheap, less capable Ethernet connection than the official Ethernet Shield.
The official shield has support built into the IDE but this board has code from very clever contributors.

Last night I rigged up the board using instruction from http://www.electrodragon.com/?p=1112 and it failed.
Not the best start.  So, I tried a few other libaries and again no success. I added voltage buffers (74HC125) to do the voltage change from 3.3V on the ENC28J60 to 5V on the Arduino.   
I asked a question at electrondragon and in fairness to him (I'm assuming him - never met them) he came back straight away with some helpful tips.
Still no luck.
Beaten, off to bed I went and then did a bit more digging today.  The 1 thing I didn't try was using an older IDE.  I took this opportunity to upgrade to Arduino IDE 1.0 where before I was using Arduino IDE 0021.

So, tonight was my second attempt.

I copied the libraries to Arduino IDE 0021 that I had been using.  I uploaded the sketch for the web server.
Opened up Firefox and browsed to 192.168.1.25.
Success 1st time.

I uploaded the ping sketch.  Success 1st time.

I then wired up an LED to Pin 4 and loaded the etherShield_web_switch sketch that allows you to control the LED from a web browser.
Again - success 1st time

Looks like the library referenced on http://www.electrodragon.com/?p=1112 from nuelectronics does not work with the latest IDE 1.0.

If you do a search for Arduino ENC28J60 in Google it will come up with stuff about using voltage convertor to convert the boards 3.3V level to the Arduino's 5V level.  At the same time it is mentioned that the Arduino can handle lower voltage (I think as low as 2V) as a HIGH, so based on the recommendation from electrondragon I just wired the ENC28J60 directly to the pins of the Arduino with no problems at all.
It worked and there was no smoke.
NOTE: As always this is FYI and your smoke and funny smells may be different.

The final hurdle I had to overcome was that the kit I have has male-male jumper wires and as you can see from the picture the ENC28J60 board has pins rather than sockets, so my wires would not work.
I considered buying some male-female wires but then figured out I could use an old HDD IDE cable to convert the pins on the ENC28J60 board to sockets for my jumper wires.

All worked really well.


Now I have the test sketches working I'll have to examine the code and figure out how to do some more interesting things now that the Arduino is connected to the network.

From searching eBay it looks like the Chinese are now manufacturing cheap W5100 based shields that also include a micr-SD slot like the offical Arduino Ethernet shield.  More expensive than the ENC28J60 board but potentially more cost effective as from my readings the W5100 based boards are supported by the built in Ethernet library so no messing with 3rd party libraries that may be out of sync with the IDE (like my experience her)  Also the W5100 by all accounts provides more of the Ethernet stack so uses less memory on the Arduino and more robust.
After messing with the ENC28J60 I expect I will get a cheap W5100 board for doing anything serious.



Finally, there is no video for this one as I'm just running the standard Examples so nothing unique or special and I thought showing my screen equivalent to the electrondragon screens would be a bit of a waste.

Onwards and upwards.


UPDATE: Below is  a follow up post to this one giving a bit more detail on the wiring and the coding.
http://winkleink.blogspot.co.uk/2012/01/arduino-enc28j60-ethernet-module-part-2.html

UPDATE August 2012: A bit more fun with the ENC28J60 and using a web server coded in PHP to control it. http://winkleink.blogspot.co.uk/2012/08/arduino-ethernet-ethercard-xamp-web.html

Thursday, July 14, 2011

Arduino - Web server controlled LED using serial connection between the Arduino and web server

I was chatting to a friend who was working on home automation.  Controlling lights, heating and other stuff around the house using a touch screen controller and I thought if you used a web site as the interface then connected to the Arduino over a serial link it would be possible to switch things on and off from any devlice that could display a web page and access the web server.

Personally, I would not recommend using a serial link from the server to the Arduino as the Arduino resets itself everytime something is sent over serial,  More correctly an ethernet shield would be great.  Giving more scalability as the web server can talk to mutliple Arduinos with no great extra effort.

I installed XAMPP on my netbook as the webserver and used PHP code on the server to present the web interface and send the command to the Arduino over serial.  The Arduino is waiting for a serial command and then depending on what it is will turn on or off the mounted LED.

So, not the most impressive looking demo, but as a proof of concept if I can turn on a LED I can control a relay to turn on an kind of device.


Below is the code.  Be aware I'm more about getting the Arduino to do something and so the code will be a bit rough around the edges.  It works but I definitely do not consider it best practise or even efficent code.
Use at your own risk.


PHP on the server:

<?php

exec('mode com4: baud=9600 data=8 stop=1 parity=n xon=no');

$switch1 = "";

/* Serial script for pan/tilt Camera with servos */
/* Script by Aneal Khimani, 2-12-10 */

//check the GET action SuperGlobal var to see if an
//action is to be performed

if (isset($_GET['action'])) {

$switch1 = $_GET['action'];

//Action required

switch ($switch1) {
case "on":
$fp = fopen("com4", "w");
fwrite($fp, chr(97));
fclose($fp);
break;

case "off":
$fp = fopen("com4", "w");
fwrite($fp, chr(98));
fclose($fp);
break;


}
}

?>

<html>
<body>
<center>

<p>
<font size="4">Flick Switch</font><br />
<table width="30">
<tr><td><a href="<?=$_SERVER['PHP_SELF'] . "?action=on" ?>">On</a></td><td><?php if($switch1 == 'on'){echo "<b>ON</b>";} ?></td></tr>
<tr><td><a href="<?=$_SERVER['PHP_SELF'] . "?action=off" ?>">Off</a></td><td><?php if($switch1 == 'off'){echo "<b>OFF</b>";} ?></td></tr>
</table>
</p>

</center>
</body>
</html>


Arduino Code:

/*

  Used with the PHP code
  http://localhost/arduino.php
 */

void setup() {               

  Serial.begin(9600); // initialize serial communication:

  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);    
}

void loop() {

// read the serial port:

if (Serial.available() > 0) {
int inByte = Serial.read();

switch (inByte) {
case 'a':
  digitalWrite(13, HIGH);   // set the LED on
  Serial.println("HIGH");
 
break;

case 'b':
  digitalWrite(13, LOW);   // set the LED off
  Serial.
  println("LOW");

break;
}

}

}

Monday, May 16, 2011

8x8 LED Matrix Scrolling Message Changing In Serial Monitor

The classic scrolling message with the ability to enter a message from the serial monitor and while it is scrolling if you enter a lowercase 'a' in the monitor it stops and you can enter a new message.

To do this I created my own character set (reminds me of the olden days with my Commodore 64 - yes I am that old)

It took 3 evenings to create the character set and then 2 evening to create the code.  So, if you are looking to do something similar the code below with the character set defined may save you some time.


Below is the code.  Be aware I'm more about getting the Arduino to do something and so the code will be a bit rough around the edges.  It works but I definitely do not consider it best practise or even efficent code.
Use at your own risk.

// Control an 8x8 LED display with 2 x 74HC595 shift registers
// Using only 3 pins from the Arduino

// while condition variable
int whileVar = 0;

//Pin connected to Pin 12 of 74HC595 (Latch)
int latchPin = 8;

//Pin connected to Pin 11 of 74HC595 (Clock)
int clockPin = 12;

//Pin connected to Pin 14 of 74HC595 (Data)
int dataPin = 11;

uint8_t led[8];
uint8_t letters[672];
uint8_t currentdisplay[8];

long counter1 = 0;

// Current Character in the charMessage Array
int charMessageCurrent = 0;

// Current line in Letter
int lineLetter = 672;

//currentChar is the current character in the charMessage that is being chekced
char currentChar =32;

// Used to store the message instead of displayMessage
char charMessage[40];

// scrollMessage is array holding the message that will be displayed
uint8_t scrollMessage[480];

// Serial read Byte
int incomingByte = 0;

void setup() {

Serial.begin(9600);
 
// Seed Random Generator with noise from analog pin 0 
randomSeed(analogRead(0));
 
//set pins to output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

// Symbol [ ] space
letters[0] =  B00000000;
letters[1] =  B00000000;
letters[2] =  B00000000;
letters[3] =  B00000000;
letters[4] =  B00000000;
letters[5] =  B00000000;
letters[6] =  B00000000;
letters[7] =  B00000000;

// Symbol !
letters[8]  =  B00000000;
letters[9]  =  B00000000;
letters[10] =  B00000000;
letters[11] =  B00000000;
letters[12] =  B11110011;
letters[13] =  B00000000;
letters[14] =  B00000000;
letters[15] =  B00000000;

// Symbol "
letters[16] =  B00000000;
letters[17] =  B00000000;
letters[18] =  B00000000;
letters[19] =  B11100000;
letters[20] =  B00000000;
letters[21] =  B11100000;
letters[22] =  B00000000;
letters[23] =  B00000000;

// Symbol #
letters[24] =  B00000000;
letters[25] =  B00100100;
letters[26] =  B11111111;
letters[27] =  B00100100;
letters[28] =  B00100100;
letters[29] =  B00100100;
letters[30] =  B11111111;
letters[31] =  B00100100;

// Symbol $
letters[32] =  B00000000;
letters[33] =  B01001110;
letters[34] =  B10010001;
letters[35] =  B10010001;
letters[36] =  B11111111;
letters[37] =  B10010001;
letters[38] =  B10010001;
letters[39] =  B01100110;

// Symbol %
letters[40] =  B00000000;
letters[41] =  B10000111;
letters[42] =  B01000101;
letters[43] =  B00110111;
letters[44] =  B00011000;
letters[45] =  B11100100;
letters[46] =  B10000010;
letters[47] =  B11100001;

// Symbol &
letters[48] =  B00000000;
letters[49] =  B01100000;
letters[50] =  B10010101;
letters[51] =  B10010011;
letters[52] =  B10010101;
letters[53] =  B10011001;
letters[54] =  B01011001;
letters[55] =  B00111110;

// Symbol '
letters[56] =  B00000000;
letters[57] =  B00000000;
letters[58] =  B00000000;
letters[59] =  B11100000;
letters[60] =  B00000000;
letters[61] =  B00000000;
letters[62] =  B00000000;
letters[63] =  B00000000;

// Symbol (
letters[64] =  B00000000;
letters[65] =  B00000000;
letters[66] =  B10000001;
letters[67] =  B01000010;
letters[68] =  B00100100;
letters[69] =  B00011000;
letters[70] =  B00000000;
letters[71] =  B00000000;

// Symbol )
letters[72] =  B00000000;
letters[73] =  B00000000;
letters[74] =  B00011000;
letters[75] =  B00100100;
letters[76] =  B01000010;
letters[77] =  B10000001;
letters[78] =  B00000000;
letters[79] =  B00000000;

// Symbol *
letters[80] =  B00000000;
letters[81] =  B10010010;
letters[82] =  B01010100;
letters[83] =  B00111000;
letters[84] =  B11111111;
letters[85] =  B00111000;
letters[86] =  B01010100;
letters[87] =  B10010010;

// Symbol +
letters[88] =  B00000000;
letters[89] =  B00010000;
letters[90] =  B00010000;
letters[91] =  B00010000;
letters[92] =  B11111111;
letters[93] =  B00010000;
letters[94] =  B00010000;
letters[95] =  B00010000;

// Symbol ,
letters[96]  =  B00000000;
letters[97]  =  B00000000;
letters[98]  =  B00000000;
letters[99]  =  B00000110;
letters[100] =  B00000001;
letters[101] =  B00000000;
letters[102] =  B00000000;
letters[103] =  B00000000;

// Symbol -
letters[104] =  B00000000;
letters[105] =  B00000000;
letters[106] =  B00000000;
letters[107] =  B00010000;
letters[108] =  B00010000;
letters[109] =  B00010000;
letters[110] =  B00000000;
letters[111] =  B00000000;

// Symbol .
letters[112] =  B00000000;
letters[113] =  B00000000;
letters[114] =  B00000000;
letters[115] =  B00000011;
letters[116] =  B00000011;
letters[117] =  B00000000;
letters[118] =  B00000000;
letters[119] =  B00000000;

// Symbol /
letters[120] =  B00000000;
letters[121] =  B10000000;
letters[122] =  B01000000;
letters[123] =  B00100000;
letters[123] =  B00011000;
letters[125] =  B00000100;
letters[126] =  B00000010;
letters[127] =  B00000001;

// Number 0 - zero
letters[128] =  B00000000;
letters[129] =  B00111100;
letters[130] =  B01000010;
letters[131] =  B10100001;
letters[132] =  B10010001;
letters[133] =  B10001001;
letters[134] =  B01000010;
letters[135] =  B00111100;

// Number 1
letters[136] =  B00000000;
letters[137] =  B00000000;
letters[138] =  B00000001;
letters[139] =  B11111111;
letters[140] =  B01000001;
letters[141] =  B00100001;
letters[142] =  B00000000;
letters[143] =  B00000000;

// Number 2
letters[144] =  B00000000;
letters[145] =  B01100001;
letters[146] =  B10010001;
letters[147] =  B10001001;
letters[148] =  B10001001;
letters[149] =  B10000101;
letters[150] =  B10000011;
letters[141] =  B01100001;

// Number 3
letters[152] =  B00000000;
letters[153] =  B01111110;
letters[154] =  B10011001;
letters[155] =  B10011001;
letters[156] =  B10011001;
letters[157] =  B10000001;
letters[158] =  B10000001;
letters[159] =  B01000110;

// Number 4
letters[160] =  B00000000;
letters[161] =  B00000100;
letters[162] =  B11111111;
letters[163] =  B01000100;
letters[164] =  B00100100;
letters[165] =  B00010100;
letters[166] =  B00001100;
letters[167] =  B00000100;

// Number 5
letters[168] =  B00000000;
letters[169] =  B10001110;
letters[170] =  B10010001;
letters[171] =  B10010001;
letters[172] =  B10010001;
letters[173] =  B10010001;
letters[174] =  B10010001;
letters[175] =  B11100010;

// Number 6
letters[176] =  B00000000;
letters[177] =  B01001110;
letters[178] =  B10010001;
letters[179] =  B10010001;
letters[180] =  B10010001;
letters[181] =  B10010001;
letters[182] =  B10010001;
letters[183] =  B01111110;

// Number 7
letters[184] =  B00000000;
letters[185] =  B11100000;
letters[186] =  B10010000;
letters[187] =  B10001000;
letters[188] =  B10000111;
letters[189] =  B00000000;
letters[190] =  B00000000;
letters[191] =  B00000000;

// Number 8
letters[192] =  B00000000;
letters[193] =  B01100110;
letters[194] =  B10011001;
letters[195] =  B10011001;
letters[196] =  B10011001;
letters[197] =  B10011001;
letters[198] =  B10011001;
letters[199] =  B01100110;

// Number 9
letters[200] =  B00000000;
letters[201] =  B01111110;
letters[202] =  B10001001;
letters[203] =  B10001001;
letters[204] =  B10001001;
letters[205] =  B10001001;
letters[206] =  B10001001;
letters[207] =  B01110010;

// Symbol :
letters[208] =  B00000000;
letters[209] =  B00000000;
letters[210] =  B00000000;
letters[211] =  B00000000;
letters[212] =  B01100110;
letters[213] =  B00000000;
letters[214] =  B00000000;
letters[215] =  B00000000;

// Symbol ;
letters[216] =  B00000000;
letters[217] =  B00000000;
letters[218] =  B00000000;
letters[219] =  B00000000;
letters[220] =  B01100110;
letters[221] =  B00000001;
letters[222] =  B00000000;
letters[223] =  B00000000;

// Symbol <
letters[224] =  B00000000;
letters[225] =  B00000000;
letters[226] =  B00000000;
letters[227] =  B10000010;
letters[228] =  B01000100;
letters[229] =  B00101000;
letters[230] =  B00010000;
letters[231] =  B00000000;

// Symbol =
letters[232] =  B00000000;
letters[233] =  B00000000;
letters[234] =  B00000000;
letters[235] =  B00100100;
letters[236] =  B00100100;
letters[237] =  B00100100;
letters[238] =  B00100100;
letters[239] =  B00000000;

// Symbol >
letters[240] =  B00000000;
letters[241] =  B00000000;
letters[242] =  B00010000;
letters[243] =  B00101000;
letters[244] =  B01000100;
letters[245] =  B10000010;
letters[246] =  B00000000;
letters[247] =  B00000000;

// Symbol ?
letters[248] =  B00000000;
letters[249] =  B00000000;
letters[250] =  B01100000;
letters[251] =  B10010000;
letters[252] =  B10001101;
letters[253] =  B10000000;
letters[254] =  B01100000;
letters[255] =  B00000000;

// Symbol @
letters[256] =  B00000000;
letters[257] =  B01111000;
letters[258] =  B10100101;
letters[259] =  B10100101;
letters[260] =  B10100101;
letters[261] =  B10011001;
letters[262] =  B10000001;
letters[263] =  B01011110;

// Letter A
letters[264] = B00000000;
letters[265] = B00111111;
letters[266] = B01001000;
letters[267] = B10001000;
letters[268] = B10001000;
letters[269] = B10001000;
letters[270] = B01001000;
letters[271] = B00111111;

// Letter B
letters[272]  = B00000000;
letters[273]  = B01110110;
letters[274] = B10001001;
letters[275] = B10001001;
letters[276] = B10001001;
letters[277] = B10001001;
letters[278] = B10001001;
letters[279] = B11111111;

// Letter C
letters[280] = B00000000;
letters[281] = B00100100;
letters[282] = B01000010;
letters[283] = B10000001;
letters[284] = B10000001;
letters[285] = B10000001;
letters[286] = B01000010;
letters[287] = B00111100;

// Letter D
letters[288] = B00000000;
letters[289] = B00111100;
letters[290] = B01000010;
letters[291] = B10000001;
letters[292] = B10000001;
letters[293] = B10000001;
letters[294] = B10000001;
letters[295] = B11111111;

// Letter E
letters[296] = B00000000;
letters[297] = B10000001;
letters[298] = B10000001;
letters[299] = B10010001;
letters[300] = B10010001;
letters[301] = B10010001;
letters[302] = B10010001;
letters[303] = B11111111;


// Letter F
letters[304] = B00000000;
letters[305] = B10000000;
letters[306] = B10000000;
letters[307] = B10010000;
letters[308] = B10010000;
letters[309] = B10010000;
letters[310] = B10010000;
letters[311] = B11111111;

// Letter G
letters[312] = B00000000;
letters[313] = B00101100;
letters[314] = B01001010;
letters[315] = B10001001;
letters[316] = B10000001;
letters[317] = B10000001;
letters[318] = B01000010;
letters[319] = B00111100;

// Letter H
letters[320] = B00000000;
letters[321] = B11111111;
letters[322] = B00001000;
letters[323] = B00001000;
letters[324] = B00001000;
letters[325] = B00001000;
letters[326] = B00001000;
letters[327] = B11111111;

// Letter I
letters[328] = B00000000;
letters[329] = B00000000;
letters[330] = B10000001;
letters[331] = B10000001;
letters[332] = B11111111;
letters[333] = B10000001;
letters[334] = B10000001;
letters[335] = B00000000;

// Letter J
letters[336] = B00000000;
letters[337] = B10000000;
letters[338] = B10000000;
letters[339] = B11111100;
letters[340] = B10000010;
letters[341] = B10000001;
letters[342] = B10000001;
letters[343] = B10000010;

// Letter K
letters[344] = B00000000;
letters[345] = B10000001;
letters[346] = B01000010;
letters[347] = B00100100;
letters[348] = B00011000;
letters[349] = B00001000;
letters[350] = B00000100;
letters[351] = B11111111;

// Letter L
letters[352] = B00000000;
letters[353] = B00000001;
letters[354] = B00000001;
letters[355] = B00000001;
letters[356] = B00000001;
letters[357] = B00000001;
letters[358] = B00000001;
letters[359] = B11111111;

// Letter M
letters[360] =  B00000000;
letters[361] =  B01111111;
letters[362] =  B10000000;
letters[363] =  B10000000;
letters[364] = B01110000;
letters[365] = B10000000;
letters[366] = B10000000;
letters[367] = B01111111;

// Letter N
letters[368] =  B00000000;
letters[369] =  B11111111;
letters[370] =  B00000010;
letters[371] =  B00000100;
letters[372] =  B00011000;
letters[373] =  B00100000;
letters[374] =  B01000000;
letters[375] =  B11111111;

// Letter 0
letters[376] =  B00000000;
letters[377] =  B00111100;
letters[378] =  B01000010;
letters[379] =  B10000001;
letters[380] =  B10000001;
letters[381] =  B10000001;
letters[382] =  B01000010;
letters[383] =  B00111100;

// Letter P
letters[384] =  B00000000;
letters[385] =  B00110000;
letters[386] =  B01001000;
letters[387] =  B10000100;
letters[388] =  B10000100;
letters[389] =  B10000100;
letters[390] =  B10000100;
letters[391] =  B11111111;

// Letter Q
letters[392] =  B00000000;
letters[393] =  B00111101;
letters[394] =  B01000010;
letters[395] =  B10000101;
letters[396] =  B10001001;
letters[397] =  B10000001;
letters[398] =  B01000010;
letters[399] =  B00111100;

// Letter R
letters[400] =  B00000000;
letters[401] =  B00110001;
letters[402] =  B01001010;
letters[403] =  B10000100;
letters[404] =  B10000100;
letters[405] =  B10000100;
letters[406] =  B10000100;
letters[407] =  B11111111;

// Letter S
letters[408] =  B00000000;
letters[409] =  B01001110;
letters[410] =  B10010001;
letters[411] =  B10010001;
letters[412] =  B10010001;
letters[413] =  B10010001;
letters[414] =  B10010001;
letters[415] =  B01100110;

// Letter T
letters[416] =  B00000000;
letters[417] =  B10000000;
letters[418] =  B10000000;
letters[419] =  B10000000;
letters[420] =  B11111111;
letters[421] =  B10000000;
letters[422] =  B10000000;
letters[423] =  B10000000;

// Letter U
letters[424] =  B00000000;
letters[425] =  B11111100;
letters[426] =  B00000010;
letters[427] =  B00000001;
letters[428] =  B00000001;
letters[429] =  B00000001;
letters[430] =  B00000010;
letters[431] =  B11111100;

// Letter V
letters[432] =  B00000000;
letters[433] =  B11111000;
letters[434] =  B00000100;
letters[435] =  B00000010;
letters[436] =  B00000001;
letters[437] =  B00000010;
letters[438] =  B00000100;
letters[439] =  B11111000;

// Letter W
letters[440] =  B00000000;
letters[441] =  B11111110;
letters[442] =  B00000001;
letters[443] =  B00000001;
letters[444] =  B00001110;
letters[445] =  B00000001;
letters[446] =  B00000001;
letters[447] =  B11111110;

// Letter X
letters[448] =  B00000000;
letters[449] =  B10000001;
letters[450] =  B01000010;
letters[451] =  B00100100;
letters[452] =  B00011000;
letters[453] =  B00100100;
letters[454] =  B01000010;
letters[455] =  B10000001;

// Letter Y
letters[456] =  B00000000;
letters[457] =  B10000000;
letters[458] =  B01000000;
letters[459] =  B00100000;
letters[460] =  B00011111;
letters[461] =  B00100000;
letters[462] =  B01000000;
letters[463] =  B10000000;

// Letter Z
letters[464] =  B00000000;
letters[465] =  B10000001;
letters[466] =  B11000001;
letters[467] =  B10100001;
letters[468] =  B10010001;
letters[469] =  B10001001;
letters[470] =  B10000101;
letters[471] =  B10000011;

// Symbol !
letters[472] =  B00000000;
letters[473] =  B00000000;
letters[474] =  B00000000;
letters[475] =  B00000000;
letters[476] =  B11110011;
letters[477] =  B00000000;
letters[478] =  B00000000;
letters[479] =  B00000000;

// Symbol "
letters[480] =  B00000000;
letters[481] =  B00000000;
letters[482] =  B00000000;
letters[483] =  B11100000;
letters[484] =  B00000000;
letters[485] =  B11100000;
letters[486] =  B00000000;
letters[487] =  B00000000;

// Symbol #
letters[488] =  B00000000;
letters[489] =  B00100100;
letters[490] =  B11111111;
letters[491] =  B00100100;
letters[492] =  B00100100;
letters[493] =  B00100100;
letters[494] =  B11111111;
letters[495] =  B00100100;

// Symbol $
letters[496] =  B00000000;
letters[497] =  B01001110;
letters[498] =  B10010001;
letters[499] =  B10010001;
letters[500] =  B11111111;
letters[501] =  B10010001;
letters[502] =  B10010001;
letters[503] =  B01100110;

// Symbol %
letters[504] =  B00000000;
letters[505] =  B00000000;
letters[506] =  B01000110;
letters[507] =  B00110000;
letters[508] =  B00011000;
letters[509] =  B00000100;
letters[510] =  B01100010;
letters[511] =  B00000001;

// Symbol &
letters[512] =  B00000000;
letters[513] =  B00000000;
letters[514] =  B00000101;
letters[515] =  B01000010;
letters[516] =  B10100101;
letters[517] =  B10101001;
letters[518] =  B01010001;
letters[519] =  B00101110;

// Symbol '
letters[520] =  B00000000;
letters[521] =  B00000000;
letters[522] =  B00000000;
letters[523] =  B11100000;
letters[524] =  B00000000;
letters[525] =  B00000000;
letters[526] =  B00000000;
letters[527] =  B00000000;

// Symbol (
letters[528] =  B00000000;
letters[529] =  B00000000;
letters[530] =  B10000001;
letters[531] =  B01000010;
letters[532] =  B00100100;
letters[533] =  B00011000;
letters[534] =  B00000000;
letters[535] =  B00000000;

// Symbol )
letters[536] =  B00000000;
letters[537] =  B00000000;
letters[538] =  B00011000;
letters[539] =  B00100100;
letters[540] =  B01000010;
letters[541] =  B10000001;
letters[542] =  B00000000;
letters[543] =  B00000000;

// Symbol *
letters[544] =  B00000000;
letters[545] =  B10010010;
letters[546] =  B01010100;
letters[547] =  B00111000;
letters[548] =  B11111111;
letters[549] =  B00111000;
letters[550] =  B01010100;
letters[551] =  B10010010;

// Symbol +
letters[552] =  B00000000;
letters[553] =  B00010000;
letters[554] =  B00010000;
letters[555] =  B00010000;
letters[556] =  B11111111;
letters[557] =  B00010000;
letters[558] =  B00010000;
letters[559] =  B00010000;

// Symbol '
letters[560] =  B00000000;
letters[561] =  B00000000;
letters[562] =  B00000000;
letters[563] =  B11000000;
letters[564] =  B00100000;
letters[565] =  B00000000;
letters[566] =  B00000000;
letters[567] =  B00000000;

// Symbol -
letters[568] =  B00000000;
letters[569] =  B00000000;
letters[570] =  B00000000;
letters[571] =  B00010000;
letters[572] =  B00010000;
letters[573] =  B00010000;
letters[574] =  B00000000;
letters[575] =  B00000000;

// Symbol .
letters[576] =  B00000000;
letters[577] =  B00000000;
letters[578] =  B00000000;
letters[579] =  B00000011;
letters[580] =  B00000011;
letters[581] =  B00000000;
letters[582] =  B00000000;
letters[583] =  B00000000;

// Symbol /
letters[584] =  B00000000;
letters[585] =  B10000000;
letters[586] =  B01000000;
letters[587] =  B00100000;
letters[588] =  B00011000;
letters[589] =  B00000100;
letters[590] =  B00000010;
letters[591] =  B00000001;

// Number 0 - zero
letters[592] =  B00000000;
letters[593] =  B00111100;
letters[594] =  B01000010;
letters[595] =  B10100001;
letters[596] =  B10010001;
letters[597] =  B10001001;
letters[598] =  B01000010;
letters[599] =  B00111100;

// Number 1
letters[600] =  B00000000;
letters[601] =  B00000000;
letters[602] =  B00000001;
letters[603] =  B11111111;
letters[604] =  B01000001;
letters[605] =  B00100001;
letters[606] =  B00000000;
letters[607] =  B00000000;

// Number 2
letters[608] =  B00000000;
letters[609] =  B01100001;
letters[610] =  B10010001;
letters[611] =  B10001001;
letters[612] =  B10001001;
letters[613] =  B10000101;
letters[614] =  B10000011;
letters[615] =  B01100001;

// Number 3
letters[616] =  B00000000;
letters[617] =  B01111110;
letters[618] =  B10011001;
letters[619] =  B10011001;
letters[620] =  B10011001;
letters[621] =  B10000001;
letters[622] =  B10000001;
letters[623] =  B01000110;

// Number 4
letters[624] =  B00000000;
letters[625] =  B00000100;
letters[626] =  B11111111;
letters[627] =  B01000100;
letters[628] =  B00100100;
letters[629] =  B00010100;
letters[630] =  B00001100;
letters[631] =  B00000100;

// Number 5
letters[632] =  B00000000;
letters[633] =  B10001110;
letters[634] =  B10010001;
letters[635] =  B10010001;
letters[636] =  B10010001;
letters[637] =  B10010001;
letters[638] =  B10010001;
letters[639] =  B11100010;

// Number 6
letters[640] =  B00000000;
letters[641] =  B01001110;
letters[642] =  B10010001;
letters[643] =  B10010001;
letters[644] =  B10010001;
letters[645] =  B10010001;
letters[646] =  B10010001;
letters[647] =  B01111110;

// Number 7
letters[648] =  B00000000;
letters[649] =  B11100000;
letters[650] =  B10010000;
letters[651] =  B10001000;
letters[652] =  B10000111;
letters[653] =  B00000000;
letters[654] =  B00000000;
letters[655] =  B00000000;

// Number 8
letters[656] =  B00000000;
letters[657] =  B01100110;
letters[658] =  B10011001;
letters[659] =  B10011001;
letters[660] =  B10011001;
letters[661] =  B10011001;
letters[662] =  B10011001;
letters[663] =  B01100110;

// Number 9
letters[664] =  B00000000;
letters[665] =  B01111110;
letters[666] =  B10001001;
letters[667] =  B10001001;
letters[668] =  B10001001;
letters[669] =  B10001001;
letters[670] =  B10001001;
letters[671] =  B01110010;


for (int i = 0; i < 8; i++){
  led[i] = letters[i];
  currentdisplay[i] = letters[i];
  }
}

void loop() {

// Clear the screen before starting
for (int i=448; i <456; i++){
  led[i-448] = letters[i];
  currentdisplay[i-448] = letters[i];;
}
screenUpdate();

// Reseting variables
whileVar = 0;
counter1 = 0;
charMessageCurrent = 0;
lineLetter = 672;
currentChar =32;

//  Start Reading the Serial Data

while (whileVar ==0){
screenUpdate();
 
// send data only when you receive data:
    if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();

                // If the byte read is an 'a' stop, otherwise add the byte to the string
                if (incomingByte ==97){
                whileVar =1;
                }
                else
                {
                charMessage[charMessageCurrent] = incomingByte;
                charMessageCurrent++;
                } 
        }
}

// End Reading Serial Data 
 

// prints charMessage
Serial.write("charMessage is: ");

for (int i=0; i<charMessageCurrent; i++){
Serial.write(charMessage[i]);
}
Serial.println("");

// Making the first 8 Bytes - character a space
for(int i =0; i <8; i++){
  scrollMessage[i] = B00000000;
}
// Move counter1 to 8 so that the space stays in place
counter1=8; 
 
for (int i=0; i < charMessageCurrent; i++){
currentChar = charMessage[i];

for (int x=7; x >= 0; x--){
  scrollMessage[counter1] = letters[((currentChar-32)*8)+x];
  counter1++;
  }
}
// End Sorting out the message for scrolling

// Clear the screen before starting
for (int i=0; i <8 ; i++){
  led[i] = B00000000;
  currentdisplay[i] = B00000000;;
}
screenUpdate();

// Reseting current1 to 0 as it is used for the delay in the code below
counter1=0;

// Resetting whileVar so it can be used again
whileVar=0;

while (whileVar ==0)
{
// Check if I enter just an a - lower case a to exit the system
    if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();

                // If the byte read is an 'a' stop, otherwise add the byte to the string
                if (incomingByte ==97){
                whileVar =1;
                }
        }  
// counter1 used for delay in animation
counter1++;

// set the LEDs
screenUpdate();

// Loop for the action - counter1 used for the delay in scrolling
if (counter1 >= 25) {
counter1 = 0;
lineLetter++;

if (lineLetter >(((charMessageCurrent)*8)+7)){
  lineLetter = 0;
  }
// Do scrolling

for (int i = 8; i > 0; i--){
  led[i] = currentdisplay[i-1];
  }
led[0] = scrollMessage[lineLetter];

for (int i=0; i <8; i++){
  currentdisplay[i] = led[i];
  }

}

}

}

void screenUpdate() {
uint8_t row = B00000001;

for (byte k = 0; k < 9; k++) {
// Open up the latch ready to receive data
digitalWrite(latchPin, LOW);
shiftIt(~row );
shiftIt(led[k] ); // LED array

// Close the latch, sending the data in the registers out to the matrix
digitalWrite(latchPin, HIGH);
row = row << 1;
  }
}

void shiftIt(byte dataOut) {
// Shift out 8 bits LSB first,
// on rising edge of clock

boolean pinState;

//clear shift register read for sending data
digitalWrite(dataPin, LOW);

// for each bit in dataOut send out a bit
for (int i=0; i<8; i++) {

  //set clockPin to LOW prior to sending bit
digitalWrite(clockPin, LOW);

// if the value of DataOut and (logical AND) a bitmask
// are true, set pinState to 1 (HIGH)
if ( dataOut & (1<<i) ) {
pinState = HIGH;
}
else {
  pinState = LOW;
}

//sets dataPin to HIGH or LOW depending on pinState
digitalWrite(dataPin, pinState);

//send bit out on rising edge of clock
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
}

//stop shifting
digitalWrite(clockPin, LOW);
}