Monday, August 24, 2009

Arduino Pointers and the Ping for Automated High Five

Here is the crosslinked article I wrote over at www.uchobby.com. This is a part of the giveaway program David is doing on the website.

Pointers, pointers to pointers, and reading information at the memory address pointed to by the pointers. These are topics that I haven’t seen addressed in the Arduino environment yet.

I was having a problem getting a variable to pass globally from one function to another. I declared the variables that I wanted to use in multiple functions globally outside all the functions and setup(). I tried declaring the variable in every function, and passing it using the return function, and putting the variable to be passed in the function call, i.e. function(variable). No success, I kept getting errors about scope, or the program will compile and upload, but the variable will be empty in the other function where I am trying to read the value.


I talked to David at uCHobby about the problem, and he pointed me to an article about using the volatile modifier on variables. It is a modifier that is rarely taught in depth but can make a difference in the programming especially when there is an optimizer in use (the Arduino uses an optimizer to make the code more efficient or take up less memory, I am not sure which, David could tell you). [David: the volatile modifier tells the compiler not to keep a local copy of a variable in a register. Its important when an interrupt could update the value making a saved copy invalid.]

I built a set of code from a few examples to try and quickly make something work. I was trying to use a PING sensor, some servos, some LEDs, and the serial monitor. I built the system I was working with one piece at a time, starting with the PING. Compile example, upload and voila. Simple. I can put my hand in front of the sensor and the serial monitor reads the distance my hand is from the sensor.

pingsensor servo

Next lets make the LEDs dim and brighten based on how far away the PING is from an object. Something like:

analogWrite(dimLED, inches);

where dimLED is a LED on a PWM pin that is dimming as the variable inches gets smaller. Success. I can make a sensor affect the LED.

Now let’s make the servo move. The Servo knob example works great for this. It lets us use an analog input to move a servo through its range. You will note that later in the actual example I put together, I did not use the servo library, or this example, but rather used an example from Robotgrrl.

Now lets make the ping sensor talk to the servo. Should be simple but the first attempt I had of this made things very jittery. The refresh rate on the servo and the PING sensor made it necessary for these to be set up as separate functions. Separate functions ended up meaning that we needed a timer to call them at timed intervals so that the refresh rates did not make the servo jittery. Separate functions and library calls eventually made it difficult to have the variables working correctly. The inches variable from the PING example was not passing to the servo function. Leaving me with a servo that did not move, but the PING was getting data. I moved the variable to make it global, and that didn’t fix the problem.

Scope errors, and undefined in this type messages drove me nuts. I consulted C++ tutorials on passing variables and global variables, and then tried the volatile modifier David at uC Hobby suggested. I talked to a computer programmer and he suggested I use pointers. Here is a good reference that helped me realize how to use pointers. I vaguely remember using pointers in my C programming class, but that was 8 years ago. I then set up the variable globalInches and a pointer to it *getInches:

int globalInches;

int* getInches=&globalInches;

To read the variables in and write the variables, as they are needed you have to reference them:

int inches1 = *getInches;

*getInches = inches;

The article about pointers goes into pointers to pointers, to pointers… and how to point to a memory address of a variable as opposed to a variable. The reason for pointing to the memory address instead of trying to pass the variable is that likely the program will try making a new variable rather than checking for the existence of a variable already. Whereas pointing to the memory address will get you the data that is in that position always. The last example they use is like this one:

int main()
{
int instruments(12);
int* p_instruments = &instruments;
int** p_p_instruments(&p_instruments);
int*** p_p_p_instruments = &p_p_instruments;
***p_p_p_instruments = 6;
}

Table for current information from above code

Variable Name Variable Type Memory Address Stored Value
instruments int 1279 6
p_instruments int* 1377 1279
p_p_instruments int** 1477 1377
p_p_p_instruments int*** 1000 1477

I put the last memory address lower than the first to show that a computer doesn’t care when a variable is declared, it will put it into memory at the first available location and during a program run, memory addresses can and will be emptied at any moment.

This makes instruments = 12, then points p_instruments to the address of instruments, then points p_p_instruments to the address of p_instruments, then points p_p_p_instruments to the address of p_p_instruments, then lastly dereferences p_p_p_instruments to put 6 in the instruments variable. Each * is a “dereference operator”, and takes the location that the variable has stored and uses it to look at the data in the memory location. The & symbol is “the address of operator”. It points the variable to the address of the variable it modifies. Reading the operators like they are called makes the line of code make more sense.

int* p_instruments = &instruments;

Reads like “int* p_instruments equals the address of instruments”.

*p_instruments = 6;

Reads like “dereferenced p_instruments equals 6”, meaning that the memory location that p_instruments is pointing to will now have 6 as it’s value. It just so happens that that memory location is the variable instruments, so now instruments = 6.

After getting it all working and tweaking the values I have a program that can make the servo with a flag on it move closer to the sensor till the servo is at or almost at the sensor, and then move it away as soon as it gets to an inch or so away. The action to start the servo to the sensor will be initiated by a button push. pushbutton

Note to programmers on keeping track of problem versions of code. In doing this example, and making it work from multiple source code parts and pieces, I ended up with many versions of the same file that all work in different fashions, or not at all. I apparently never saved any of the ones that had numerous errors in them, and I should have made a separate sketch folder for failed code, so that I could go back and see what didn’t work in doing this example. As it is I have only the memory of variable failures, and not the code to show and repeat the errors for this article. I wish I had a library of the bad code to be able to give the exact errors that came up.

highfive1The physical pin outs for the example is as follows using a Bare Bones Board kit:

Bare Bones Board Arduino in the breadboard

4 pin momentary on push-button with one pin at pin 2, one on the opposite side to 5+, and one to

ground with a pull down resistor

Servo with power and ground to the respective power lines, and the signal to pin 6

PING sensor with power and ground to the respective power lines, and the signal to pin 7

LED to pin 13 and ground

Here is the breadboard and Bare Bones Board with the sensor, servo, pushbutton and LED hooked up ready to go for this example.

/*
||
|| @file highfivePINGaervo.pde
|| @version 1.0
|| @author Charles Stutzman
|| @contact charlesd.stutzmansr@gmail.com
||
|| @description
|| | This sketch takes a button push and initiates a high five style motion from a servo to a PING
|| | sensor.
|| | based off of the TimedAction example ThreeExamplesAtOnce.pde by Alexander Brevig
|| | alexanderbrevig@gmail.com
|| | has three TimedActions, that interact and initiate a high five motion, and one that is a
|| | heartbeat to show activity on the board
|| | May contain parts and pieces from Ardiuno Examples Library (PING, Blink LED, Button
|| | digital Input, and http://robotics.learnhub.com/lesson/1766-arduino-and-servos
|| #
||
*/

#include 
//TimedAction initialization of the circuits heartbeat
TimedAction heartbeatAction = TimedAction(1000,heartbeat);

//TimedAction initialization of the Servo position function
TimedAction servoAction = TimedAction(20,servo);

//TimedAction initialization of the PING sensor read function
TimedAction pingAction = TimedAction(200,ping);

//TimedAction initialization of the button push for the start of a "high five" between the servo flag //and the PING sensor
TimedAction buttonAction = TimedAction(50,button);

// globalvariables for ping and servo functions
int globalInches;
int* getInches=&globalInches;

//heartbeat variables and pins
const int ledPin = 13;
boolean ledState = false;

//servo variables and pins
const int servo1 = 6;
int servoAngle1;
int pulseWidth1;

//ping variables and pins
const int pingPin = 7;

//button pins and variables
const int buttonPin= 2;
int buttonState = 0;

//set up for servo position setting
void servoPulse1 (int servo1, int servoAngle1) {
pulseWidth1 = (servoAngle1 * 11) + 500; // Converts angle to microseconds
digitalWrite(servo1, HIGH); // Set servo high (turns it on)
delayMicroseconds(pulseWidth1); // Wait a very very small amount
digitalWrite(servo1, LOW); // Set servo low (turns it off)
// Typical Refresh cycle of servo (20 ms) normally a delay would be here, but the delay is in the //TimedAction calls
}

void setup() {
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin,ledState);
Serial.begin(9600);// there for debugging and watching the sensor values
pinMode(servo1, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop() {
heartbeatAction.check(); //trigger every second
servoAction.check(); //trigger every 20 millisecond
pingAction.check();//trigger every 200 millieconds
buttonAction.check();//trigger every 50 milliseconds
}

//checks for a button push to initiate the "high five"
void button() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH){
*getInches = 6;// makes globalInches go to a value that the servo will move when the servo checks //the value
}
}

//beats the LED at pin 13 at 1 beat per second as a heartbeat
void heartbeat() {
ledState ? ledState=false : ledState=true;
digitalWrite(ledPin,ledState);
}

//moves the servo according to data in *getInches
void servo() {
int inches1 = *getInches;
if (inches1 > 2) {
if (inches1 < 7) {
servoAngle1 = inches1*3;
}
}
else {
servoAngle1 = 60;
}
servoPulse1(servo1, servoAngle1);
Serial.print(inches1);
Serial.println(" inches from sensor."); //datalogging for debugging
}

//gets data from the ping sensor
void ping() {
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
long duration, inches;

// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);

delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);

// The same pin is used to read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);

// convert the time into a distance
inches = microsecondsToInches(duration);
Serial.print(inches);
Serial.print(" inches is what the sensor just read.");//there to help identify the number
Serial.println();

*getInches = inches;
}

long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are
// 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
// second). This gives the distance travelled by the ping, outbound
// and return, so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf

return microseconds / 74 / 2;
}

Here is the sequenced pictures of the action:

highfive

Have fun and enjoy making the Arduino interact with others and its environment.

Charles Stutzman


Article continued after the jump...

Scrounging a Desk Phone

This is the first article I wrote over at www.UcHobby.com, cross listed over here so anyone finding me first here can see what I have done in the past.

Scrounging is a good way to get parts your your electronics workshop. Rather then throwing away that old piece of electronics, take it apart to salvage reusable parts. In this article an old Small Business 4 line Phone is salvaged for parts. This article was submitted by Charles Stutzman as part of the uCHobby giveaway program.


phoneuntouchedHow often do we see an office throw away good electronic components in the guise of slightly malfunctioning items, or doing a blanket upgrade to a new system. I work in a small business with 3 people in the office, and we have a 4 line phone system. Every time our boss decides we need to get a new phone, he buys one for every phone location, so that they interact with each other, allowing use of the intercom, and hold functions. This leaves anywhere from 4-8 good used phones being put to the curb. The need for a good alphanumeric LCD got me looking at that pile a little closer, and I decided to start scrounging. On opening the case I found more parts than I would ever have thought. Most of these are generic resistors, diodes, capacitors and the like, but there are a few items like headers, RJ11 and RJ14 connectors, a 12 volt power supply(wall wart), and that 16X2 LCD that happens to be a common interface type, with plenty of data to be able to use it, even one article showing how you can use dip switches, a breadboard, and a few other common items to manually drive it as if you were the software (I am thinking my daughter would love to play with that).

backwithleveleroffTools needed: small Phillips head screwdriver, Flathead screwdriver (for prying open the handset), de-soldering gun (or heat gun), and optionally a cordless drill (makes it all go quicker).

First flip the phone over so you can see its back, some of these have a plastic pop off piece that makes the phone sit at an angle. These usually are popped off with a release tab. There should be four to eight small Phillips head screws usually at the corners. Take those out. You don’t have to remove the battery cover screw unless you need a good nine volt battery contact set, but you might still want to check the charge on the nine volt, why throw a good project battery.

phonebackbatteryout

After the four to eight screws are removed, you can split the case and you will have two to three cables connecting the top to the bottom half. One to the LCD, and the other two go to the keypad. Unplug these from their headers on the bottom board carefully so you can reuse the headers and cables.

phonepulledapartcablesconnected

Now you have two separate halves of the phone, and you can see the goodies inside. As mentioned before the main things of interest will be RJ14 and RJ11 jacks, headers with matching cables (14, 10, and 9 pin), 16X2 alphanumeric LCD, Piezoelectric speaker, and microphones.

After looking at the boards and seeing if there are any obvious items you are interested, then you can make note, and start taking it apart. I first went to the LCD which is attached by four Phillips head screws.

LCD2

Most of these have a clear plastic guard that unless scratched can be reused in your projects as long as you don’t scratch it. Next attached by entirely too many screws is the keypad, which is useless unless you can figure out its logic processes for each button.

keypaduntouched

I look at it as too much to play with for now, but will keep the item in case I get a wild hair to tackle a challenge. I may take one of these and cut around the board to use each button as a single switch, by soldering wires to each trace and breaking the line beyond the wire splice in. Removing the board with all the goodies on it is simple, it has four screws holding it on. After it is removed you can put it in a vise, or clamp, and start removing components that you are interested in.

mainboarduntouched

The handset is really simple to pull apart, and get a mic, piezo-speaker, and RJ14 connector.

phonehandsetopenedI started with the through hole components since I can reuse them easily. There are capacitors, transformers, RJ14 and RJ11, headers, and more. The heat gun method makes this process quick if you are careful. I did a full pull apart of this board with the heat gun freeing only the surface mount parts, in 15 – 25 minutes. The total tear apart from fully intact phone to as far as I pulled it apart, in 30 – 45 minutes. Below are pictures of the items I have scrounged. Mainly it boils down to capacitors, capacitors, capacitors, with a sprinkling of other surface mount parts. Listed out the components are as follows: 1 16X2 alphanumeric LCD screen, 2 transformers, 4 reed relays, 4 fuses, 3 RJ14 jacks, 2 RJ11 jacks, 1 stereo headphone jack, 1 power port with matching 12 volt 500ma wall wart. 2 microphones, 1 piezoelectric speaker, 1 normal speaker, about 10 resistors of varying value, and about 40 varying size capacitors.

micsandspeakerfromhandsetRJconnectorsb

I decided not to remove surface mount parts, as I can’t use them currently, but they are still there to be used by anyone else who wants to go further with a tear down.
Here is the board empty of all the through hole components.

scroungedboardnothroughpinsleft

There is an article from Everyday Practical Electronics, February 1997, by Julyan Ilett, titled "How to Use an Intelligent LCD". It can be found here. With a breadboard, some resistors, a dip switch array (8 switches), two momentary on switches, a variable Potentiometer, and the scrounged LCD from the phone system, you can make up a small manual operated LCD screen. The article walks through manually operating an LCD based on the HD44780 controller. Searches for the HD44780 controller interface will yield info for you to integrate with many different microprocessors.
The parts can be identified fairly easily for the standard items using Google. A search for transistor part number KSP 44 214 pictured below right

0423091836

This search will get you many sites, and this is where I found information, fairchildsemi.com with information as to how the item is marked. We find out that the transistor is a three lead, with collector/emitter voltages of 400V and dissipation of 625 mW. The capacitors are easy to identify as they are marked for their size in most applications, usually. The blue and the white components shown are a little more difficult to determine. The harder to identify parts on the left of the picture are as follows: the blue items is a varistor, and the white is a capacitor.

unknowntransformers

These items I believe are 4 pin relays, but I am guessing on that, as the searches are coming up empty when I look by Cosmo and 4010 and c16 which are the markings on them.

The transformers are tricky, but some simple experimentation could give you some data on it.

assorted

The fuse is useful, the push button is potentially useful, and the reed relay (the 8 pin IC type chip).
There are a few really difficult items such as an item marked TECOM 561-100006 HJ66 0224 to find info about, and in reality looks like a component made up of many surface mount parts, in a heat shrink wrap with pins coming off in an inline fashion, with 17 pins.

I hope that this scrounge article helps others have ideas as to new places to scrounge. I plan to use the LCD soon, and the rest of the parts as needed. I may tear a few apart so I can have a few LCDs at least. You may notice that the phones changed in the pictures, because I already had one mostly scrounged when I realized that I didn’t have photos of the process that were usable, so I started scrounging a second one.
A list of the scrounged items is as follows:

  1. 42 capacitors from 1 microfarad to 220 microfarad
  2. 4 black 4 pin photo coupler anode cathode emitter collector
  3. 3 black 2 pin 682j inductors
  4. 2 102j 2 pin white inductors
  5. 4 8 pin reed switches D2A050002
  6. 4 ksp44 transistors epitaxial silicon transistors collector base 500v collector emitter 500v emitter base 6v
  7. 7 varied resistors
  8. 1 5.5v .47F Super capacitor useful as backup power for CMOS
  9. 1 121j – 120 uH inductor
  10. 5 varistors light blue flat discs brand _ _ _ varistor voltage – _ tolerance (k-10% l-15%,m -20%) – _ Type (disc or square) – _ _ element diameter
  11. 4 EPCOS tantalum chip capacitors
  12. 3 152j – 1.5 uH inductor
  13. many screws
  14. 2 transformers

The easiest way I have found with modern technology to identify parts is to type all of the markings on the part into a Google search, and refine your search from there. If you then find numerous instances of the same repeated part of the markings such as, the 4 reed switches made by KUAN HIS. A search for KUAN HSI D2A050002 C35 results in no matches, but drop the C35 and you get 2 results. If you go the first link you find that the part number is D2A050002 and the manufacturer is KUAN HSI. Drop the Manufacturer and you can obtain more manufactures of the common part, and then if you weed through the results you should be able to find a data sheet for the item in question. You may have to omit some numbers to get rid of date codes, or manufacturer’s plant codes, the last digit or three. I never found a data sheet for a D2A050002, but I did find one for a D2A050000, at alldatasheet.com.

More info on uses for the LCD can be found on uCHobby.com.

Charles Stutzman


Article continued after the jump...

Websites for the hobby electronics community

I recently started playing with hobby electronics, and so far I have found a few places to be absolutely invaluable, at least towards my current slant of projects. I got hooked looking at all the DIY Hack websites available, and currently look to see what others are doing on a regular basis at www.hacknmod.com, www.hackaday.com, and www.hackedgadgets.com. These website have plenty of ideas and examples of projects for hobby guys to play with. I eventually ran across www.UcHobby.com, where there are contests, and great giveaway programs to encourage the hobby community.

David Fowler of www.UcHobby.com is an excellent source of information and encouragement for the hobby electronics craft-person. I wrote my first article (also linked to here) for the electronics community for his giveaway program. What an encouragement to get free stuff for a little time investment that I was going to do anyway to learn more about the hobby I am getting into. The Bare Bones Board from www.moderndevice.com is a very capable arduino clone, aka freeduino, and is wonderful because it plugs into most breadboards fairly easily.

The open source nature of the item makes it very easy to learn and use if you have even the slightest knowledge of C or similar programming language. I am looking forward to the continued gain in knowledge that this hobby will bring me, and I hope to contribute back to the community as well.

Charles Stutzman

Article continued after the jump...

Article number 2 at UcHobby.com

Here is the link to the second article I wrote at www.uchobby.com, about integrating PING, Servos, and using Pointers in the Arduino IDE. Again I will post the whole article over here soon...

Charles Stutzman
Article continued after the jump...