Arduino bit array

Sometimes even using a byte of memory takes up too much space, especially when working with simple true / false values of 1′s / 0′s. I have created a library which allows you to split a byte into 8 individual bits, based on the Arduino bitWrite and bitRead, this library allows you to create an array of 8 bits in a byte, effectively allowing you to store 8 boolean variables in the space that just one previously occupied – a massive saving in memory space. This allows you to store much more data in the Arduino’s RAM, this could possibly be used for mapping applications etc.

This example sketch shows you how to use the library:


#include "bitArray.h" //Here we include the library in our code

bitArray bitOne(1, 0, 1, 1, 1, 0, 1, 0); //Here we create a new bit array, setting each bit as we create the array
bitArray bitTwo; //here we create a bit array without setting any bits, this creates an empty array which is just populated by zero's

void setup(){

Serial.begin(9600); //We start the Serial

Serial.print("bitArray one: ");
Serial.print(bitOne.readBit(0)); //We read the bit from location of the bitOne array, we set this bit as 1 when creating the array
Serial.print(bitOne.readBit(1));
Serial.print(bitOne.readBit(2));
Serial.print(bitOne.readBit(3));
Serial.print(bitOne.readBit(4));
Serial.print(bitOne.readBit(5));
Serial.print(bitOne.readBit(6));
Serial.println(bitOne.readBit(7));

bitTwo.writeBit(0, 1); //we set the first bit of the bitTwo array to 1

Serial.print("bitTwo: ");
Serial.print(bitTwo.readBit(0)); //we read data from bitTwo's first location
Serial.println(bitTwo.readBit(1));

}

void loop(){
}

To download the library, please visit the github site.

Arduino live debugger

The ability to pause an Arduino sketch is something I feel the platform has been missing. Because of this I have written a simple library, which allows you to place pauses in the sketch for debugging purposes. Once you have uploaded your sketch, it will run until it hits a pause, alerting you and suppling info. You can then type ‘y’ into the Serial feed to continue until you reach the next pause.

I have uploaded the library to github:

http://www.github.com/jacobsax/pdebugger

Multi Servo Control from Computer

In response to a request, I have created a program which allows for multi servo control through Processing. Connect two servo’s to pins 9 and 10 of your Arduino, as shown in my previous blog post, wich has got much more information on using potentiometers: Servo_control_via_potentiometer. You will also need to ensure you have the Servo library for Arduino (again more is detailed in my last blog post).

To control servo’s using your computer, you will need to use Processing. This is an incredibly useful java based programming language, wich makes it really easy to communicate with the Arduino. You can find out more at processing.org .

Connecting your Arduino to a computer is as simple as plugging it in to a USB port. Then, when you load the processing file below, look in the black box at the bottom of the screen to see a list of ports available on your computer, and which one the Arduino is using, then change the number in Serial.list()[0] to match whatever port is being used.

 

import processing.serial.*;

Serial myPort;  // Create object from Serial class

PFont f;

void setup() {
  size(640, 130);
  
  println(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
  
     f = createFont("Times New Roman",16,true);
     
}

void draw() { 
  fill(95);
  textFont(f, 16);
  text("Control Two Servo, switch between then using the number 1 and 2 keys on your keyboard", 10, 30);
  text("Use the L key to rotate the servo 90' left, and the R key to rotate it 90' Right", 10, 60);
  text("Use the S key to return to the center", 10, 90);
}

void keyPressed() {
  
  switch (key) {
    case 'a':
      println("A pressed");
      myPort.write('l'); //turns left
      break;
    case 's':
      println("S pressed");
      myPort.write('s'); //stops turning
      break; 
    case 'd':
      println("D pressed");
      myPort.write('r'); //turns right
      break;     
    case '1':
      println("Using servo 1");
      myPort.write('1'); //controlling servo 1
      break;
    case '2':
      println("Using servo 2");
      myPort.write('2'); //controlling servo 2
      break;
    default:  
      break;
  }
}

 

And the arduino code:

 

// Controlling two servo positions using a processing file
//Created by Jacob Unwin - http://www.jacob-unwin.com
 
#include <Servo.h>
  
Servo myservo_one;  // create servo object to control a servo
Servo myservo_two;

byte currentServo;
  
char val;
  
void setup()
{
  myservo_one.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo_two.attach(10); //attaches the 2nd servo on pin 10
  
  myservo_one.write(90); //sets both servo's at 90 degrees
  myservo_two.write(90); 
  
  Serial.begin(9600); //start serial output at 9600
}
  
void loop()
{
   
  if(Serial.available()){
    val = Serial.read();
     
    if (val == '1'){ //if 1 has been pressed, current servo is 1
      currentServo == 1;
    } else if (val == '2'){ //else if 2 has been pressed, current servo is 2
      currentServo == 2;
    }
     
    if (val == 'l') { //if the last key press was l, rotates to 0 degrees
       if (currentServo == 1){
         myservo_one.write(0);
       } else {
         myservo_two.write(0);
       }
    }
     
    if (val == 'r') { //if the last key press was r, rotates to 180'
      if (currentServo == 1){
         myservo_one.write(180);
       } else {
         myservo_two.write(180);
       }
    }
     
    if (val == 's') { //if the last key press was s, returns to the center
      if (currentServo == 1){
         myservo_one.write(180);
       } else {
         myservo_two.write(180);
       }
    }
   
  }

  }

 

To control the servo, first select wether you want to control servo one or two by pressing the 1 or 2 keys on your keyboard. Then you can rotate the servo left (to 0 degrees) using the L key, to the center (90 degreed) using the S key, and to the right (180 degrees) using the D key. This code could be further modified to add more servo’s, and create a more accurate rotation, i.e. with each key press moving the servo by only 1 degree.

Using a Real Time Clock with an Arduino

A Real Time Clock, or RTC, is a small computer chip that uses a crystal to keep time. It can output that time as a string of numbers. This post will explain how you can use a RTC with the Arduino, and implement this data into your sketches.

The RTC I use in this article is produced by sparkfun. To wire it up, connect the SDA pin to analogue pin 4 on the Arduino, the SCL pin to analogue pin 5, the gnd pin to the ground pin on the Arduino, and the 5v pin to the 5v supply from your Arduino. Whilst it is possible to use this clock without a library, it is much simpler to use the RTC library produced by JeeLabs.

Using the example code in the library, you can take readings from the clock, and reset its’ time based on your computer time.

*This post comes as part of a series of posts, which will lead to the creation of an LED ring clock.

Making a 7-Segment Display Countdown Clock

In this article I will show you how to control a basic seven segment display from an Arduino. I will then show you how it can be made into a simple countdown timer.

The seven segment display I use in this post is from spark fun. It is an anode display, meaning that it draws its power through two pins. To make individual segments light up, you turn off the power to the corresponding pin, lowering the resistance and allowing that segment to make a complete circuit. This is useful if you have a large number of displays, as it means that the Arduino does not have to power the display. If you have a common cathode display, just reverse all of the code i.e. where it saiys digitalWrite(A, HIGH); make it digitalWrite(A, LOW) and so on.

Now its time to wire up the display, connect the power pin to the 3.3v plug on your Arduino, remembering to place a 330ohm resistor between the power supply and the display. Then connect he other pins on the display to pins two to nine on your Arduino board, for the spark fun display, there is an image below to help you understand which pins control which segments on the display.

G connects to pin 2 on the Arduino, F to 3, A to 4, B to 5, E to 6, D to 7, C to 8, and 9 to dp (although I don’t use the decimal point in any of these tutorials.

Then, using the code below, you can display numbers zero to nine on the display,  changing the void loops content to change which numbers appear on the display.


const int G = 2;
const int F = 3;
const int A = 4;
const int B = 5;
const int E = 6;
const int D = 7;
const int C = 8;
const int dp = 9;

void setup() {

pinMode(G,2);
pinMode(F,3);
pinMode(A,4);
pinMode(B,5);
pinMode(E,6);
pinMode(D,7);
pinMode(C,8);
pinMode(dp,9);

}

void loop() {

counter();
/*change this field to control which
number you want to appear on the display.
counter - counts from 0-9
zero - shows zero
one - shows 1
two - shows 2
three - shows 3
four - shows 4
five - shows 5
six - shows 6
seven - shows 7
eight - shows 8
nine - shows 9
*/

}

void counter(){
zero();
delay(990);
one();
delay(990);
two();
delay(990);
three();
delay(990);
four();
delay(990);
five();
delay(990);
six();
delay(990);
seven();
delay(990);
eight();
delay(990);
nine();
delay(990);
}

void off(){ //turns off all lights
digitalWrite(G, HIGH);
digitalWrite(F, HIGH);
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, HIGH);
digitalWrite(dp, HIGH);
delay(10);
}

void zero(){
digitalWrite(G, HIGH);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void one(){ //turns on
digitalWrite(G, HIGH);
digitalWrite(F, HIGH);
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void two(){
digitalWrite(G, LOW);
digitalWrite(F, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, HIGH);
digitalWrite(dp, HIGH);
delay(10);
}

void three(){
digitalWrite(G, LOW);
digitalWrite(F, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void four(){
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void five(){
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(E, HIGH);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void six(){
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void seven(){
digitalWrite(G, HIGH);
digitalWrite(F, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void eight(){
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void nine(){
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

Here we have the basis of our counter, including commands for each number. The void fields for each number displayed help to make the code more efficient, as it means that we don’t have to continually write out the same sequence each time we want to display that number on our display, instead you just have to link to the void in question i.e. one();

Now we can add a button to start our timer. I have used a momentary push button which can be bought from anywhere, although I got mine from spark fun, whilst these buttons are not as accurate as some other buttons, they are very cheap and easy to use. To wire it up, connect a 3.3v power to the left hand pin, then an 10k resistor and the Arduino input to the right hand pin, off of the resistor you can run a ground wire, linking back to the Arduino.

Once the button is connected, you can upload the code. You may notice that I have reversed the counter void, so that it counts down from nine. I have also created 3 values to be used with the push button, val, oldval and state. By recording the current and previous value, a much more accurate determination of the buttons state can be made, helping to improve the accuracy of our counter.


/* This code creates an arduino based counter, that counts down
from nine to zero when a button is pressed

Automatic checking of the buttons state to ensure accuracy

Written by Jacob Unwin (http://www.jacob-unwin.com/ ), a tutorial
can be found at http://wp.me/p2xDON-1e

This code is free to use and share

*/

const int G = 2; //creates an instance of the pin G
const int F = 3;
const int A = 4;
const int B = 5;
const int E = 6;
const int D = 7;
const int C = 8;
const int dp = 9;

const int button = 10; //creates aninstance of button

int buttonState = 0; //holds the current state of the button
int buttonVal = 0; //holds the buttons current value
int buttonOldVal = 0; //holds the buttons previous value

void setup() {

pinMode(G,2); //sets int G to pin 2 etc.
pinMode(F,3);
pinMode(A,4);
pinMode(B,5);
pinMode(E,6);
pinMode(D,7);
pinMode(C,8);
pinMode(dp,9);

}

void loop() {

buttonVal = digitalRead(button); //reads the state of button

/*decides on the state of the button based on current and
previous values */
if ((buttonVal == HIGH) && (buttonOldVal == LOW)){
buttonState = 1 - buttonState;
delay(10);
}

buttonOldVal = buttonVal; //saves the current button value as the old button value

if (buttonState == 1){ //if the button hsa been pressed
counter(); //run void counter (display counter)
} else { //if not
zero(); //run void zero (display zero)

}

buttonState = 0; //resets the button state before the loop is re-run
//stopping the counter from continually repeating

}

void counter(){ //creates a counter void
nine();
delay(990);
eight();
delay(990);
seven();
delay(990);
six();
delay(990);
five();
delay(990);
four();
delay(990);
three();
delay(990);
two();
delay(990);
one();
delay(990);
zero();
delay(990);
off();
delay(500);
zero();
delay(500);
off();
delay(500);
}

void off(){ //turns off all lights
digitalWrite(G, HIGH);
digitalWrite(F, HIGH);
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, HIGH);
digitalWrite(dp, HIGH);
delay(10);
}

void zero(){ //shows the number zero
digitalWrite(G, HIGH);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void one(){ //shows the number one
digitalWrite(G, HIGH);
digitalWrite(F, HIGH);
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void two(){ //shows the number two
digitalWrite(G, LOW);
digitalWrite(F, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, HIGH);
digitalWrite(dp, HIGH);
delay(10);
}

void three(){ //shows the number three
digitalWrite(G, LOW);
digitalWrite(F, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void four(){ //shows the number four
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void five(){ //shows the number five
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(E, HIGH);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void six(){ //shows the number six
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void seven(){ //shows the number seven
digitalWrite(G, HIGH);
digitalWrite(F, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void eight(){ //shows the number eight
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, LOW);
digitalWrite(D, LOW);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

void nine(){ //shows the number nine
digitalWrite(G, LOW);
digitalWrite(F, LOW);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(E, HIGH);
digitalWrite(D, HIGH);
digitalWrite(C, LOW);
digitalWrite(dp, HIGH);
delay(10);
}

Once you have uploaded this code, the display should show the number zero. Pressing the button should start a countdown from nine to zero, and then return the display to showing zero. Additional displays could be added through the use of shift registers (a tutorial will be added at a later date). You could also streamline this code, whilst I have kept it simple so that is is easy to understand, it is possible to compress all of the digitalWrite commands for each number into one line, reducing the size of the code considerably.

Servo Control via Potentiometer

This tutorial explains how to directly interface with a servo via a potentiometer, using an Arduino. It ensures that the input and output are calibrated correctly, so that the servo and potentiometer remain in sync, and allows you to view readings through a serial viewer. When writing this code, I used extracts from the calibrate example in the Arduino library, and code from the Michal Rinott tutorial on the arduino.cc site.

In case you didn’t know, a potentiometer is a variable resistor, which can be used to adjust a power output according to how far open / closed it is. With the Arduino you can read this change as an analog input, allowing for high control over inputs. I used a potentiometer from spark fun. It is actually called a Trimpot, but this is basically just a really small potentiometer. You could use a bigger one if you prefer.  On the potentiometer you should have three pins, to wire it up, connect the left hand pin to the 3.3v power supply on the Arduino. Then connect the centre pin to analog pin 1 (A1) on your Arduino, and the right hand pin to the ground pin on the Arduino (place a 330 ohm resistor in-between the right hand pin and the ground pin).

Using this code, you should be able to read the analog output of the potentiometer in a serial viewer.

//Reading the value of a potentiometer and displaying it on a serial output
//Created by Jacob Unwin, using code from Michal Rinott tutorial

int sensorValue = 0;         // the sensor valueint sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value
int sensor = 1;  // analog pin used to connect the potentiometer

void setup()
{

  Serial.begin(9600); //start serial output

}

void loop()
{
  sensorValue = analogRead(sensor);            // reads the value of the potentiometer (value between 0 and 1023)
  Serial.print(sensorValue);  //print the servo value in degrees in the serial monitor
  Serial.println();

}

Now its time to wire up the servo. This is more complicated, as it needs an external power supply to ensure you don’t burn out your Arduino. You will need a switch, a 6v power pack (a set of 4 aa batteries in a holder will do), and a smallish servo. Plug the battery back into the switch, so that you can use it to turn the battery pack on and off. Alternatively you could just unplug the battery pack each time you wan’t to turn off the Arduino. You will find 3 coloured wires coming out of the servo. Connect the red one to the power packs positive wire (probably red), and connect the black wire to the ground strip on your breadboard. To the same ground strip connect a ground wire to the Arduino, and another to the power pack. Whilst you are doing this, make sure the power pack is turned off. Finally, connect the white or yellow wire on the servo to pin 9 on the Arduino. This is the control wire, which we will use to control the rotation of the servo.

 

 

I also connected an additional momentary push button to my Arduino, which allows for the device to be re-calibrated whilst in use. You’d don’t need to do this, it is just personal preference. Connect the left hand pin to the 3.3v power supply,and the right hand pin of the button to pin 7 on the Arduino and to the Arduino’s ground pin (via a 330 ohm resistor).

To use this code, you will need to download and install the Servo library.

If it is wired up correctly, plug in the Arduino, turn on the power pack, and then upload the code. The servo should move in sync with the potentiometer.

 
// Controlling a servo position using a potentiometer (variable resistor)
// Added callibration function to ensure accurate control of servo
// Written by Jacob Unwin, code used from Michal Rinott tutorial

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int sensorValue = 0;         // the sensor value
int sensorMin = 1023;        // minimum sensor value
int sensorMax = 0;           // maximum sensor value

int sensor = 1;  // analog pin used to connect the potentiometer
int button = 7;

int buttonVal = 0; // sets the value
int state = 0; //sets the state
int old_val = 0; //stores the previous value

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(button, INPUT); //sets the button as an input

  myservo.write(180);

  // calibrate during the first five seconds
  while (millis() < 5000) { //for the first five seconds
    sensorValue = analogRead(sensor);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }
  }

  // signal the end of the calibration period
  myservo.write(0);

  Serial.begin(9600); //start serial output
}

void loop()
{
  buttonVal = digitalRead(button);
  sensorValue = analogRead(sensor);            // reads the value of the potentiometer (value between 0 and 1023)
  sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(sensorValue);                  // sets the servo position according to the scaled value
  sensorValue = constrain(sensorValue, 0, 179); //in case the sensor value is outside the range seen in callibration
  delay(15);                           // waits for the servo to get there

  Serial.print("servo = " );
  Serial.print(sensorValue);  //print the servo value in degrees in the serial monitor
  Serial.println();

  if((buttonVal==HIGH) && (old_val==LOW)){ //checks if there was a transition between old and new val
  state = 1 - state; //sets the state
  delay(10); //sets a delay of 10
}

old_val = buttonVal; //stores the new value as the old value

if (state==1) {

  calibrate();
}

}

void calibrate(){

  myservo.write(180);

  // calibrate during the first five seconds

    sensorValue = analogRead(sensor);

    // record the maximum sensor value
    if (sensorValue > sensorMax) {
      sensorMax = sensorValue;
    }

    // record the minimum sensor value
    if (sensorValue < sensorMin) {
      sensorMin = sensorValue;
    }

  // signal the end of the calibration period
  myservo.write(0);

  delay (2000);

}