Showing posts with label howto. Show all posts
Showing posts with label howto. Show all posts

Thursday, February 28, 2019

Arduino - avrdude: stk500_getsync() not in sync - How to fix


This is  reminder for me and hopefully useful for others either new to Arduino or using different boards.

Sometimes on uploading you can get an error message

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00




Of course the attempt number changes as it tries 10 times.

There are a few relatively obvious things that can help stop this error message.

Select the right board.  If you're using an Uno, select Uno. If you're using a Leonardo, select Leonardo.

Select the correct processor: ATMega328 is the Uno one and the default

Make sure your USB port is selected.

Even after doing both of these and it all looking right you might still be getting the error message.

This is where we get into a discussion about Arduino compatible boards.  The Arduino is an Open Source design and so it is perfectly legal and acceptable for anyone to copy the design and make their own boards and sell them (but they cannot call it an Arduino, topic for another day)

Some of these compatible boards use a different USB chip (CH340) and the ATMega328 could have a different bootloader to the actual Arduino.

if you are using a compatible board that has a CH340 make sure to install the driver for the chip otherwise you may not even be able to see the board in the IDE.

Then for the bootloader there is an alternative option under the Processor called "ATMega328P (Old Bootloader)"  Not where I expect to see an alternative bootloader option but there it is.


ATMega328p (Old Bootloader)


This is the one I have to use for compatible boards.

So, once the correct board, processor, and port are selected you should be able to program your Arduino with ease.

Finally, finally. If you're running Linux and not Windows there is one more thing to take into account and that's permissions.  By default a regular user account does not have permission to read/write to USB serial ports so you have to add your user to the group with access. 

The command you need is as follows where [USERNAME] is replaced with your username.

sudo usermod -a -G dialout [USERNAME]


WARNING: This command is run using sudo and so has root access.  It's always the right thing when finding commands online that use sudo to do your own research before blindly using the command.
So, here's where I got the command from https://www.arduino.cc/en/Guide/Linux/


Hope you find this useful as I expect I'll be back here again when I set up my next computer or buy some new compatible boards.


Monday, January 30, 2017

Controlling screen brightness on pi-topCEED on Raspbian Jessie with guizero app and keyboard shortcut

I backed the pi-topCEED during the crowd funding campaign and have used it a lot since.

pi-topCEED

My kids also use it for homework and general Minecraft playing.
As I like to make things I have a number of microSD which means I regularly use it with Raspbian Jessie.

There are a couple of drawback to using Raspbian on the pi-topCEED.  The pi-topHUB doesn't shutdown the power completely leaving the backlight on and the Raspberry Pi in kind of a suspecd mode. The red LED is still on.  Also, there is no way to control the screen brightness.

Doing the usual Google to see if there was a way around this I came across this GitHub repository that looked like it would do the job.  https://github.com/rricharz/pi-top-install
It includes code to shutdown the pi-topHUB which also completely shuts down power to the display and to the Pi as well as provide a program called 'brightness' to control the screen brightness.

After following the instructions in the README.md I had the pi-topHUB shutting down correctly and if from the terminal I type brightness increase the screen brightness would go up and vice versa brightness decrease did what you'd expect.

All very good, but not very user friendly if you're running the GUI which is where I spend most of my time. 

With that in mind and having recently heard good thing about guizero (https://github.com/lawsie/guizero) which is based on tkinter and is said to make building GUI apps  in Python easier.

It looked to me like a simple app with 2 buttons [Darker] [Brighter] is all I needed so I read up a little on guizero.  Using the App using grid layout example (https://lawsie.github.io/guizero/app/) I soon has a small app that did exactly what I wanted.
Code available on Git Hub (https://github.com/winkleink/pi-top-brightness)

The program itself is quite short. Code below.  This makes 2 buttons.  Button1 and Button2.  When you press them they run the relevant system comment to change the brightness. 


from guizero import *
from subprocess import call

def brighter():
    call(["brightness", "increase"])

    
def darker():
    call(["brightness", "decrease"])
    
    
app = App(title="pi-top", height=50, width=145, layout="grid", bgcolor=None)

button1 = PushButton(app, brighter, text="Brighter", grid=[0,1])
button2 = PushButton(app, darker, text="Darker", grid=[0,0])
app.display()


Here is a video showing it working.


After a quick chmod +x  pi-top-brightness-gui.py the program was executable and so I could run it directly.

Then I added the program to the main menu under the System Tools section.
In the video you can see I have a pi-top icon.  This I took from their Twitter account (https://twitter.com/GetPiTop)  I expect they'll be OK with that as I'm adding even more branding to my pi-topCEED.
I explained in a recent post on backing up Minecraft Worlds how to add a program to the menu (http://www.winkleink.com/2016/07/minecraft-pi-backup-worlds-on-exit.html)

It's great to have a little gui app to change the brightness of the screen and even better to learn a new skill with guizero.

One thing I didn't mention is that when I rebooted the Raspberry Pi the first time after installing the programs the screen brightness was far lower than I wanted it be by default.

To fix this I added a single line cronjob.  Crontab with cronjobs is a way to schedule when programs run automatically with one of the options being to run at boot up. It's a simple way to get something running each time you login. It's the system used by people who lets say want to check their network connection every hour.  Just setup a cronjob to run every hour and it will take care of it for you.   I used this previously to enable the Bluetooth keyboard and trackpad or the NexDock. (http://www.winkleink.com/2016/10/nexdock-thoughts.html)

So, I used crontab to set the brightness of the screen to 8 on startup.

In the terminal type:

crontab -e

If this is your first time it asks which editor you want to use.  I do [2] for nano.
Then the crontab file is opened where you put the jobs you want to run.
There are some comments in the file to help you get started, but if you want to do serious scheduled jobs then it's worth 

Go to the bottom of the file and type

@reboot brightness 8

Then the usual nano [CTRL]-[x] to save and close.  Answering [y] to save the file with the same name

Now when I start up the pi-topCEED the default brightness is '8' which suits me.


Finally, finally, the rricharz GitHub explains how to set the keyboard shortcuts for the pi-top laptop so the brightness keys work.  All good if I had a pi-top laptop, but I have a pi-topCEED where it's bring your own keyboard and the one I'm using doesn't have any fancy keys.
So, I looked up how to add keyboard shortcuts.  Again, it ends out to be not too hard.  Just added a couple of entries into a config file.

First thing I had to do is decide what key combination I wanted to use. I settled on:
[Shift]-[Windows Key]-[Up Arrow] for brighter
[Shift]-[Windows Key]-[Down Arrow] for darker

To do this you need to edit the lxde-pi-rc.xml file.
The file is a in a hidden folder in your home folder. If using the default user pi then the following command will open it 

nano /home/pi/.config/openbox/lxde-pi-rc.xml

As the file is in the home folder it doesn't need sudo to edit it

Then scroll down to the keyboard section and add the following to the end.
Easiest way is in nano find the </keyboard> text using the command [Ctrl]-[w] to do a Where is

Make sure you use spaces for the indent and get the <keybind> to line up with the other <keybind> entries

    <keybind key="S-W-Up">
      <action name="Execute">
        <command>brightness increase</command>
      </action>
    </keybind>
    <keybind key="S-W-Down">
      <action name="Execute">
        <command>brightness decrease</command>
      </action>
    </keybind>

To finish like above use [Ctr]-[x] to save and close.

To test select [shutdown] in the drop down menu and then [logout].
No need to reboot to enable the keyboard shortcuts.
Once you log back in the lxde-pi-rc.xml setting will be re-enabled and the 2 new key bindings will be active giving you the ability to change the brightness of your pi-top/pi-topCEED using [Shift]-[Windows Key]-[Up Arrow] and [Shift]-[Windows key]-[Down Arrow]

This has been a fun little project to improve the use of the pi-topCEED.
I like the work rricharz has done getting the pi-topHUB to turn off completely and to control the brightness as well as Laura Sach has done to make guizero so easy to use.

With the help of other peoples effort I now have the pi-topCEED completely shutdown as well as the Raspberry Pi and the ability to change the screen brightness using either a little gui app or with the keyboard.  Not a bad result for a couple of hours.

If you have any questions let me know in the comments.


Friday, May 8, 2015

Created a game in Scratch

I came across some videos of Jeff Minter who created some amazingly original games in the 8 bit era and is still going strong developing new games today and it got me thinking of one of his stranger games that I remember playing on the Commodore VIC-20.
Meta Galactic Llama Battle at the Edge of Time.  Here's a video of it on the Commodore 64. I can't remember if I had it for the C64 as well, but definitely played it on the VIC-20


As with most of Jeff Minters games it kind of takes a slightly different approach.
You're a Llama at the bottom of the screen and you can move left and right.  You can exit one side of the screen and come in the other side as well.
You shoot lasers out of your mouth at 45 degrees and you have to shoot the spiders falling from the top of the screen.
If a spider reaches the ground it starts to crawl towards you making evasive action essential. 
All very interesting so far.  To add to the complexity and the control you can also raise and lower a ceiling for your laser to bounce off of to assist in shooting the spiders.

 I had great fun with this game all those years ago and so wanted to see if I could re-create something similar using Scratch.

After some fumbling I put created a little game inspired by the Llamas.

Below is the game and here is a Link to project on Scratch website if you want a peek inside. https://scratch.mit.edu/projects/61239650/




It's been fun developing a game in Scratch. I'm most definitely not an expert and I expect there are a lot of refinements that could be done to the code to improve the game but it plays similar to the original.  I hope you enjoy it.

Monday, April 13, 2015

List of online resources to assist in learning to code

The final session of the robot club at my kids school was Easter break and I promised them a handout detailing resources that are free they can use to continue to learn to code.  The kids were aged 10-12 and most were very new to coding so wanted to give a range of resources.  
They've spend the last term building small robots with an Arduino as the main controller so included Arduino as well as general programming resources.

As per the sheet a great combination for new people starting out if they don't have any hardware is the Earthshine Electronics guide and the AtuoDesk 123D Circuits online electronics and Arduino emulator.  The guide gives 14 projects of varying degrees of complexity from an electronics and programming standpoint and the AutoDesk 123D Circuits gives you a free resource to do your coding. The electronics pieces is done on a breadboard and is very visual. Reminds me of Fritzing.


https://drive.google.com/file/d/0B23BvTk93HRYSmZzU2RnclhhRlU/view?usp=sharing


If you'd prefer not to download the handout here is the list of links

Websites



BBC Dr. Who programming game - http://www.bbc.co.uk/cbbc/games/doctor-who-game




Books and Reading Material

Invent with Python - https://inventwithpython.com/

Earthshine Electronics – Arduino Starter Kit Manual - http://thearduinoguy.org/?page_id=100

YouTube Channels

Jeremy Blum, Tutorial Series for Arduino - http://bit.ly/1xrxqvr

Kevin Durrah - https://www.youtube.com/user/kdarrah1234/featured

The New Boston - https://www.youtube.com/user/thenewboston/featured

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);
}