Monday, January 26, 2015

SainSmart L298N Motor Controller

I got a SainSmart 4WD Robot Kit, which contains the L298N Motor Controller. There's not a lot of documentation of how to use this, and much of what exists by users of the board is just plain wrong. I put together a short tutorial (as part of a much more comprehensive robot kit manual I'm writing), on how to use this controller, and make a simple robot that goes forwards, backwards, and turns left or right.

Schematic:



Code:

//declaring the pins for the IN pins on the L298N
const int rightForwardPin = 3;
const int rightBackwardPin = 5;
const int leftBackwardPin = 6;
const int leftForwardPin = 9;

int runTime = 5000;

void setup() {
  //Stating that the pins are OUTPUT
  pinMode(rightForwardPin, OUTPUT);
  pinMode(rightBackwardPin, OUTPUT);
  pinMode(leftForwardPin, OUTPUT);
  pinMode(leftBackwardPin, OUTPUT);
  Serial.begin(9600);
}

//Looping to test the wheels of the car
void loop() {

  forward();
 
  stopCar();
 
  backward();
 
  stopCar();
 
  left();
 
  stopCar();
 
  right();
 
  stopCar();
}

//Setting the wheels to go forward by setting the forward pins to HIGH
void forward(){
  Serial.println("Forward");
  digitalWrite(rightForwardPin, HIGH);
  digitalWrite(rightBackwardPin, LOW);
  digitalWrite(leftForwardPin, HIGH);
  digitalWrite(leftBackwardPin, LOW);
  delay(runTime);
}

//Setting the wheels to go backward by setting the backward pins to HIGH
void backward(){
  Serial.println("Backward");
  digitalWrite(rightForwardPin, LOW);
  digitalWrite(rightBackwardPin, HIGH);
  digitalWrite(leftForwardPin, LOW);
  digitalWrite(leftBackwardPin, HIGH);
  delay(runTime);
}

//Setting the wheels to go right by setting the rightBackwardPin and leftForwardPin to HIGH
void right(){
  Serial.println("Right");
  digitalWrite(rightForwardPin, LOW);
  digitalWrite(rightBackwardPin, HIGH);
  digitalWrite(leftForwardPin, HIGH);
  digitalWrite(leftBackwardPin, LOW);
  delay(runTime);
}

//Setting the wheels to go left by setting the rightForwardPin and leftBackwardPin to HIGH
void left(){
  Serial.println("Left");
  digitalWrite(rightForwardPin, HIGH);
  digitalWrite(rightBackwardPin, LOW);
  digitalWrite(leftForwardPin, LOW);
  digitalWrite(leftBackwardPin, HIGH);
  delay(runTime);
}

//Setting the wheels to go stop by setting all the pins to LOW
void stopCar(){
  Serial.println("Stop");
  digitalWrite(rightForwardPin, LOW);
  digitalWrite(rightBackwardPin, LOW);
  digitalWrite(leftForwardPin, LOW);
  digitalWrite(leftBackwardPin, LOW);
  delay(1000);
}



Video:

Saturday, January 17, 2015

Optical Tachometer

A while back I discussed a IR emitter / detector pair, and talked about building a optical tachometer for determining the RPM of a fan or motor. So now I'm making good on that promise. Connect the emitter / detector as shown in the previous post, using pin 2 on the Arduino (interrupt 0). Put something reflective on one blade of the fan, or cover one half of the motor shaft with black tape, to get one trigger per revolution. We based this project on the work found at http://elimelecsarduinoprojects.blogspot.com/2013/06/measure-rpms-arduino.html.



// based on http://elimelecsarduinoprojects.blogspot.com/2013/06/measure-rpms-arduino.html
// read RPM and calculate average every then readings.
const int numreadings = 10;
int readings[numreadings];
unsigned long average = 0;
int index = 0;
unsigned long total;

volatile int rpmcount = 0;
unsigned long rpm = 0;
unsigned long lastmillis = 0;

void setup(){
 Serial.begin(9600);
 attachInterrupt(0, rpm_fan, FALLING);
}

void loop(){


 if (millis() - lastmillis >= 1000){  //Update every one second, this will be equal to reading frequency (Hz).

 detachInterrupt(0);    //Disable interrupt when calculating
 total = 0;
 readings[index] = rpmcount * 60;  // Convert frequency to RPM, note: this works for one interruption per full rotation. For two interrupts per full rotation use rpmcount * 30.

 for (int x=0; x<=9; x++){
   total = total + readings[x];
 }

 average = total / numreadings;
 rpm = average;

 rpmcount = 0; // Restart the RPM counter
 index++;
 if(index >= numreadings){
  index=0;
 }


if (millis() > 11000){  // wait for RPMs average to get stable

 Serial.print(" RPM = ");
 Serial.println(rpm);
}

 lastmillis = millis(); // Update lastmillis
  attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
}


void rpm_fan(){ // this code will be executed every time the interrupt 0 (pin2) gets low.
  rpmcount++;
}


Sunday, January 11, 2015

CoPiino, The Melding of Arduino and Raspberry Pi

The CoPiino is a Arduino compatible Atmel 1284 based "shield" for the Raspberry Pi that allows remote editing and uploading of Arduino sketches using a web browser. Access the CoPiino app running on the Raspberry Pi with a web browser to edit and upload new sketches. Transfer sensor data from the CoPiino to the Raspberry Pi for display by the Apache Web Server, and stored by the MySQL server running on the Pi.



Saturday, January 10, 2015

Preparing a Used SDCard for Raspberry Pi

I'm preparing a previously set up SDCard for Installing a CoPiino (Arduino Hat for Raspberry Pi). The problem is that Windows only recognizes the first partition on a SDCard. Here are the steps I took to remove the old Raspberry Pi partitions, and prepare the card for a new Raspian install.

DISKPART
Start a command prompt, and type in DISKPART and press Enter to start the DISKPART console. List all of your disks by typing LIST DISK, then select the proper disk with SELECT DISK # (where # is obviously the SD card). You can then type CLEAN (MAKE SURE YOU SELECTED THE PROPER DISK!), and it will clear the partition table on the card. To create a primary partition to reuse the space on the card, type CREATE PARTITION PRIMARY. This will then reallocate the previously "cleaned" space.


SD FORMATTER
Download SD FORMATTER and format the SDCard.

DOWNLOAD & COPY THE RASPIAN IMAGE
Go to http://www.raspberrypi.org/help/noobs-setup/ and follow the instructions for downloading and copying the image to the SDCard. Then boot the Rasperry Pi, and finish the install normally.

Monday, January 5, 2015

Interfacing an Old School 15 pin Joystick

Today I'm working with an older PC style 15 pin joystick. This predates the newer USB joysticks by a couple of decades, and makes it a lot easier to interface with the Arduino. I'm using a joystick shield that's made by Lectrobox, with a Joystick made by Suncom. Any 15 pin IBM PC Joystick will work fine. It's only wired for one joystick, so you would need two shields for two joysticks, or mod the shield (moderate difficulty), for use with a Y splitter.

There's no wiring involved, and the onboard jumpers allow you some selection in Arduino pins.

Note: To connect a PS/2 keyboard, see http://www.instructables.com/id/Creating-the-PS2-Keyboard-smart-interface-for-micr/


The sample code provided outputs the analog positions of the stick, and the digital positions of the two buttons:


I'd recommend using interrupts for the buttons (pins 2 & 3) so as to not miss button presses, with some debounce code, but that will take some moderate shield modifications. You will probably have to play with your stick adjustments to get zero readings at rest. You can build your own shield, with a female 15p D Sub, and wire it for 2 joystick operation if you want, or stack a second shield. See http://www.built-to-spec.com/blog/2009/09/10/using-a-pc-joystick-with-the-arduino/ for more info. A Y Splitter Cable would allow two joysticks to a single port in this scenario. The joystick Shield above only is wired fore one.

Thursday, January 1, 2015

Arduino Christmas Light Sequencer

I've always enjoyed watching those Youtube videos where someone has sequenced all their Christmas lights to music. Some are very elaborate. I wonder, what could I do with a Arduino and a SainSmart 8 relay board? I found a project on Instructables where a guy built his own relay board. Since I already have one from SainSmart, that eliminated half the complexity of the project right there. He already had the relay timing worked out, so I needed to figure out what notes to play, and put those notes into his sketch so that they played in sequence with the lights. I pulled up some sheet music only, and started a spread sheet, where each note is an event. I broke down the song into it's 57 notes, listed the word parts that go with each note, figured out the frequency of each note, and inserted the appropriate Tone / noTone pairs in the code.

Video (still uploading to Youtube) posted below the code.

Arduino 2560 (you can use a UNO just as easily)
SainSmart 8 Channel Relay (16 channel available)
Piezo Module
Christmas Tree Light Strings (up to 8, or 16, can link up to 3 end to end)
After Christmas sales on light strings are awesome!

Note to Frequency List
Joy to the World sheet music
Virtual Piano

Connections:

on Relay board:
Gnd to Arduino Gnd
VCC to; Arduino +5
IN1-8 to Arduino 12-5

Piezo:
- to Arduino Gnd
S to Arduino 4 (I'm using a Mega 2560)

Christmas Light Strings:

Cut one wire that goes from the plug to the first light in the string. Loop it through one of the relays on the board, using the Normally Open and Common contact in series with that cut wire. See our previous relay post for details.

Code:

int tree1 = 5;
int tree2 = 6;
int tree3 = 7;
int tree4 = 8;
int tree5 = 9;
int tree6 = 10;
int tree7 = 11;
int tree8 = 12;
int s = 150;
int ds = 225;
int e = 300;
int de = 450;
int q = 600;
int dq = 900;
int h = 1200;
int dh = 1800;


int pPin = 4;

void setup()
{
  pinMode(tree1, OUTPUT);
  pinMode(tree2, OUTPUT);
  pinMode(tree3, OUTPUT);
  pinMode(tree4, OUTPUT);
  pinMode(tree5, OUTPUT);
  pinMode(tree6, OUTPUT);
  pinMode(tree7, OUTPUT);
  pinMode(tree8, OUTPUT);
  digitalWrite(tree1,LOW);
  delay(1000);
  digitalWrite(tree2,LOW);
  delay(1000);
  digitalWrite(tree3,LOW);
  delay(1000);
  digitalWrite(tree4,LOW);
  delay(1000);
  digitalWrite(tree5,LOW);
  delay(1000);
  digitalWrite(tree6,LOW);
  delay(1000);
  digitalWrite(tree7,LOW);
  delay(1000);
  digitalWrite(tree8,LOW);
  delay(1000);
  digitalWrite(tree1,HIGH);
  digitalWrite(tree2,HIGH);
  digitalWrite(tree3,HIGH);
  digitalWrite(tree4,HIGH);
  digitalWrite(tree5,HIGH);
  digitalWrite(tree6,HIGH);
  digitalWrite(tree7,HIGH);
  digitalWrite(tree8,HIGH);

}

void loop()
{


  // event 1
  noTone(pPin);
    digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 261.63); // c4
  delay(q);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 2
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 246.94);  // b3
  delay(de);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 3
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 220); // a3
  delay(s);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 4
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 196); // g3
  delay(1050);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 5
  digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 174.61); //f3
  delay(s);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 6
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 164.81); //e3
  delay(q);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 7
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 146.83); // d3
  delay(q);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 8
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 130.81); //c3
  delay(dq);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 9
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 196); // g3
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  // event 10
  digitalWrite(tree2, LOW);
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 220); // a3
  delay(dq);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  digitalWrite(tree7, HIGH);
  // event 11
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 220);  // a3
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  // event 12
  digitalWrite(tree3, LOW);
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 246.94); //b3
  delay(dq);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  digitalWrite(tree6, HIGH);
  // event 13
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 246.94);  //b3
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  // event 14
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree3, LOW);
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  digitalWrite(tree6, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 261.63); //c4
  delay(dq);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  digitalWrite(tree6, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  // event 15
  digitalWrite(tree8, LOW);
  tone(pPin, 261.63); //c4
  delay(e);
  noTone(pPin);
  digitalWrite(tree8, HIGH);
  // event 16
  digitalWrite(tree1, LOW);
  tone(pPin, 261.63); //c4
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  // event 17
  digitalWrite(tree7, LOW);
  tone(pPin, 246.94); //b3
  delay(e);
  noTone(pPin);
  digitalWrite(tree7, HIGH);
  // event 18
  digitalWrite(tree2, LOW);
  tone(pPin, 220); //a3
  delay(e);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  // event 19
  digitalWrite(tree6, LOW);
  tone(pPin, 196); //g3
  delay(e);
  noTone(pPin);
  digitalWrite(tree6, HIGH);
  // event 20
  digitalWrite(tree3, LOW);
  tone(pPin, 196); //g3
  delay(de);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  // event 21
  digitalWrite(tree5, LOW);
  tone(pPin, 174.61); //f3
  delay(s);
  noTone(pPin);
  digitalWrite(tree5, HIGH);
  // event 22
  digitalWrite(tree4, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  // event 23
  digitalWrite(tree8, LOW);
  tone(pPin, 261.63); //c4
  delay(e);
  noTone(pPin);
  digitalWrite(tree8, HIGH);
  // event 24
  digitalWrite(tree1, LOW);
  tone(pPin, 261.63); //c4
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  // event 25
  digitalWrite(tree7, LOW);
  tone(pPin, 246.94); //b3
  delay(e);
  noTone(pPin);
  digitalWrite(tree7, HIGH);
  // event 26
  digitalWrite(tree2, LOW);
  tone(pPin, 220); //a3
  delay(e);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  // event 27
  digitalWrite(tree6, LOW);
  tone(pPin, 196); //g3
  delay(e);
  noTone(pPin);
  digitalWrite(tree6, HIGH);
  // event 27
  digitalWrite(tree3, LOW);
  tone(pPin, 196); //g3
  delay(de);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  // event 29
  digitalWrite(tree5, LOW);
  tone(pPin, 174.61); //f3
  delay(s);
  noTone(pPin);
  digitalWrite(tree5, HIGH);
  // event 30
  digitalWrite(tree4, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  // event 31
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 32
  digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 33
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 34
  digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 35
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 164.81); //e3
  delay(75);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 36
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 174.61); //f3
  delay(75);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 37
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 196); //g3
  delay(dq);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 38
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 174.61); //f3
  delay(75);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 39
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 164.81); //e3
  delay(75);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 40
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 146.83); //d3
  delay(e);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 41
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 146.83); //d3
  delay(e);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 42
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 146.83); //d3
  delay(e);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 43
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 146.83); //d3
  delay(75);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 44
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 164.81); //e3
  delay(75);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 45
  digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 174.61); //f3
  delay(dq);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 46
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 164.81); //e3
  delay(75);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  // event 47
  digitalWrite(tree2, LOW);
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 146.83); //d3
  delay(75);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  digitalWrite(tree7, HIGH);
  // event 48
  digitalWrite(tree3, LOW);
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 130.81); //c3
  delay(e);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  digitalWrite(tree6, HIGH);
  // event 49
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree3, LOW);
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  digitalWrite(tree6, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 261.63); //c4
  delay(q);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  digitalWrite(tree6, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  // event 50
  digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 220); //a3
  delay(e);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 51
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 196); //g3
  delay(de);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 52
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 174.61); //f3
  delay(s);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 53
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  tone(pPin, 164.81); //e3
  delay(e);
  noTone(pPin);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  // event 54
  digitalWrite(tree3, LOW);
  digitalWrite(tree6, LOW);
  tone(pPin, 174.61); //f3
  delay(e);
  noTone(pPin);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree6, HIGH);
  // event 55
  digitalWrite(tree2, LOW);
  digitalWrite(tree7, LOW);
  tone(pPin, 164.81); //e3
  delay(q);
  noTone(pPin);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree7, HIGH);
  // event 56
  digitalWrite(tree1, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 146.83); //d3
  delay(q);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree8, HIGH);
  // event 57
  digitalWrite(tree1, LOW);
  digitalWrite(tree2, LOW);
  digitalWrite(tree3, LOW);
  digitalWrite(tree4, LOW);
  digitalWrite(tree5, LOW);
  digitalWrite(tree6, LOW);
  digitalWrite(tree7, LOW);
  digitalWrite(tree8, LOW);
  tone(pPin, 130.81); //c3
  delay(h);
  noTone(pPin);
  digitalWrite(tree1, HIGH);
  digitalWrite(tree2, HIGH);
  digitalWrite(tree3, HIGH);
  digitalWrite(tree4, HIGH);
  digitalWrite(tree5, HIGH);
  digitalWrite(tree6, HIGH);
  digitalWrite(tree7, HIGH);
  digitalWrite(tree8, HIGH);
  delay(10000);

}



Tuesday, December 30, 2014

Programming the Leixen VV-898 with CHIRP

Previously I posted about manually programming the new Leixen VV-898 from Radioddity, and tonight had the opportunity to program the radio using CHIRP and the programming cable Radioddity just sent me. I downloaded CHIRP, plugged in the cable, and downloaded the settings from my radio. I made a couple of changes, and uploaded the changes back to the radio. What follows are the steps I took, and a video of my setup. Enjoy!


  • Install the CHIRP software 
  • If you get a message that the software may not have installed properly, just override and click the button to tell it that it did.
  • Plug in usb cable into the computer, wait for prolific driver to install (can take a few minutes). then plug the other end into the radio (microphone jack)
  • Now run the chirp program (it will be on your programs menu)
  • Click "Radio" on the menu, and choose "Download from radio"
  • You will be asked for the port number, vendor (Leixen), and the model (VV-898). click ok.
  • A "cloning from radio" progress bar pops up.
  • When it's done, the radio will play a  tune, and a spreadsheet of your settings will show.
  • Make changes per your repeater requirements. 
  • Click radio on the menu, and upload your changes back to the radio.
Official CHIRP Documentation - http://chirp.danplanet.com/projects/chirp/wiki/Beginners_Guide

Video:

D Shell connectors, DB-9's and other Nonsense

30 + years in IT, and I remember many tech's and computer folks talking about DB-9 serial connectors. I needed a d connector for a joystick to Arduino project, and found to my amazement we've been calling them wrong for years (ok, so I kinda remember the correct terminology, but the wrong ones were so commonly used). The Joystick uses a DA-15, the Serial a DE-9, and the printer used a DB-25. D stood for the shape of the shell, the second letter (A, B, C, or D) stood for the size, and the numeral, the number of pins or sockets. VGA is a DE-15HD, or High Density.

http://en.wikipedia.org/wiki/D-subminiature


I don't even want to get into the "RJ-45" Connector naming issue, but I guess I will. Ethernet does not use a RJ-45 connector. Ethernet uses a 8P8C connector. a RJ-45 is a mechanically-keyed variation of the 8P8C body with an extra tab that prevents it from mating with other connectors, used in telecom applications.

http://en.wikipedia.org/wiki/Registered_jack#RJ45

Hope this sheds some light on issues you never knew were an issue, LOL

Thursday, December 18, 2014

Packt5Dollar $5 Dollar Tech Book / Video Sale

Merry Christmas! Take advantage of Packt5Dollar‬ this Holiday! Electronics and Programming books -

The $5 eBook Bonanza is here!

Treat yourself to the eBook or Video of your choice for just $5 and get as many as you like until January 6th 2015. To get you started, we've put together the Top 20 Titles of 2014 for you to pick up here. But don’t forget, you can get ANY eBook or Video for $5 in this offer.

http://bit.ly/1x20UiM

Founded in 2004 in Birmingham, UK, Packt’s mission is to help the world put software to work in new ways, through the delivery of effective learning and information services to IT professionals.

Working towards that vision, we have published over 2000 books and videos so far, providing IT professionals with the actionable knowledge they need to get the job done –whether that’s specific learning on an emerging technology or optimizing key skills in more established tools.

As part of our mission, we have also awarded over $1,000,000 through our Open Source Project Royalty scheme, helping numerous projects become household names along the way.

Wednesday, December 17, 2014

Remote Reprogramming your Arduino

Need to make changes to a Arduino that's remote? Monitor, Control, even reprogram remotely using your web browser on any platform from phone, tablet, or pc.

Connect the $30 CoPiino "HAT" to a Raspberry Pi, install the BlueberryC software, and you can remotely control and reprogram the onboard Arduino compatible. Full shield compatibility with existing Arduino shields.





Tuesday, December 9, 2014

SainSmart Support Forum Back Online!


The SainSmart support forum is back online! SainSmart is one of my favorite sources for Arduino's, Raspberry Pi's, and related sensors and modules. I've posted some of my favorite projects there, and will be posting more soon. Come and learn more about the products they sell, programming, electrical connections, and more. Post your favorite SainSmart based projects. Welcome to the SainSmart Community! http://www.sainsmart.com/vanilla/

Tuesday, November 18, 2014

Emulating An Arduino Sketch in a Spreadsheet

Many times I'll mock up my Arduino formulas in a spreadsheet before I start building a sketch. One of the more complicated Arduino commands to emulate is the MAP command.

The Arduino code:

height = map(adc, 171, 512, 12, 0);

In Excel becomes:

= (adc-in_min)*(out_max-out_min) / (in_max-in_min) + out_min

The following emulates a voltage divider that converts a fluid level of a container to gallons. It uses a reverse map as decreasing resistance of the sensor means increasing depth.


Sunday, November 16, 2014

Installing & Programming the VV-898 2m / 70cm Ham Radio

Ricky and I installed my new Leixen VV-898 2m/70cm 10 watt dual band Ham Radio in my truck today. It's $135 delivered, from http://www.radioddity.com. Ricky pulled out the ashtray and installed the radio in the exposed cavity. I then wired the power to the power leads from the old cigarette lighter (radio is about 10 watts, lighter can handle 150 watts), and we ran the antenna cable under the seats and out the back window (temporary, there's a rubber plug in the floor behind the seat).

UPDATE: I've programmed two of our "local" repeaters, one on the SCHeart system (Murrel's Inlet, SC), and one on the PALS system (Greelyville, SC). Both are about 35 miles from me (Andrews, SC) in opposite directions. I'm getting great signal reports, and both TX and RX is clean and clear.

Programming the radio to talk to our local repeater was a bit of a challenge (Software programming further down). Complete details were not in one place. I've collected the bits, and assembled them in an orderly and easy to follow collection.

In order to program the radio, you need to put it into Frequency mode (defaults to Channel mode). Press B on the Mic, and verify the channel + and - buttons actually change the frequency, and not the channel number.

Now enter the frequency of your repeater output using the numeric buttons on the Mic. I could not enter 146.805 (kept going to 146.800), so I knew the step was off.

Press M (which puts you in Menu mode), and CHA+ till you get to Menu 41. Press M again to enter Menu 41, and CHA+ until step says 5KHz. Press M again to back out to Menu.

Now enter the frequency of your repeater with the Mic keypad.

Press M to enter Menu mode, then:

Press CHA + or - to Menu 34, Press M to enter, and CHA- or + to pick your offset (600 KHz for us), then M again to exit.

Press CHA + or - to Menu 35, then M to enter. Set the offset type to -RPT (or whatever your repeater uses) with the CHA+ or -, then M to exit out.

Press CHA + or - to Menu 10, press M to enter, and CHA + or - to select CTC, then M to exit.

Press CHA + or - to Menu 11, press M to enter, and CHA + or - to select CTC Code (85.4 in our case), then M to exit.

Press CHA + or - to Menu 5, press M to enter, and CHA + or - to select Channel 1 (or whatever channel you want to save to), then M to exit.

Wait 3 or 4 seconds for the timeout to exit Menu, and press B to exit Frequency Mode. Now you should be able to use the CHA + or - to select saved channels.

Find out more - http://www.radioddity.com/us/lx-898-mobile-radio-60db-4w-10w-dtmf-vehicle-mobile-dual-band-transceiver-136-174-400-470mhz.html








If you have a Kenwood programming cable, a USB -> TTL adapter, or want to make one, you can download the CHIRP programming software, and build a cable adapter like the following:


Wednesday, November 12, 2014

The MQTT Connection

MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging “machine-to-machine” (M2M) or “Internet of Things” world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

The MQTT protocol is based on the principle of publishing messages and subscribing to topics, or "pub/sub". Multiple clients connect to a broker and subscribe to topics that they are interested in. Clients also connect to the broker and publish messages to topics. Many clients may subscribe to the same topics and do with the information as they please. The broker and MQTT act as a simple, common interface for everything to connect to. This means that you if you have clients that dump subscribed messages to a database, to Twitter, Cosm or even a simple text file, then it becomes very simple to add new sensors or other data input to a database, Twitter or so on.

The Arduino makes a handy MQTT client, and Mosquitto (yes, with two T's) on the Raspberry Pi makes a handy MQTT broker (server).

An example Arduino project

What can you build?

Arduino Networking

As much fun as it is connecting sensors to an Arduino, and displaying data on a LCD, lighting LED's, or other local actions, the real power is when you connect to a network. Whether it's a local network and you are communicating between them or collecting data in a central database (Raspberry Pi), or connecting to the internet and contributing local weather data to a server, or broadcasting data with email or Twitter, even pulling down information like emails, tweets, or scraping other websites for data for local display, there's a lot of fun to be had.

One book that explains how this all works, and gives you easy to replicate (and understand) projects is "Arduino Networking" by my friend Marco Schwartz. This book delves into the abilities of network connectivity, explaining how and why it works, and leaves your mind swirling with new applications, and the ability to execute them. It's a must have on any maker's shelf!

Communicate with Marco at his Forum "Open Home Automation" on G+