profmason.com

May 18, 2012

Arduino embedded into boebot form factor

Filed under: Daily — profmason @ 9:35 pm

The rest of the parts finally came in so here is a first picture of the arduino embedded directly into the boebot form factor.  Everything works fine and I had it driving around on the desk.  It is programmable from the Arduino environment via the USB connector shown.  I haven’t soldered in the central connector yet since they haven’t come in.  The Silk screen is missing lots of info. The only mistake I have found so far is that the switch is backwards (off is on the right).  I also left off the 9V connector.  I just realized that I mounted the breadboard upside down.  Credit to the acrob  project and Richard Balogh who generously shared their schematics.

The board cost $4 in small quantity, but I should be able to get it down to ~$2.5 if I can shave 2mm off the length.  Parts are ~$10.

  • ATMEGA 168 or 328 with bootloader: $5
  • Power Jack: $0.20
  • Female Double Pin header $.40
  • Mini Breadboard $1.70
  • Switch $0.40
  • Reset Button $0.1
  • 78L05 $0.3
  • Crystal $0.15
  • Caps $0.30
  • LEDS $0.10
  • Female 0.1 connector $0.5
  • Resistors $0.1
  • Male 0.1 connectors $0.4

The programming link is a standard CPS2102 USB to TTL converter from ebay for ~$2.5

April 17, 2012

Robomagellan Antenna Switch

Filed under: Daily — profmason @ 8:37 pm
  • Brown to Ground
  • Orange to +5
  • Brown and White Left Switch
  • Orange and White Right Switch

The switches read 0V when not engaged and then 5V (With a 10K current limiting resistor) when activated.  The wires can be shaped, but please be careful to not over stress the connection points.

Here is a simple sketch to read the antenna sensors:

/*
  Read Antenna Switch
 The circuit:
 * RIGHT Switch to pin 12
 * LEFT Switch to pin 11
 */

// constants won't change. They're used here to set pin numbers:
const int RightAntenna = 12;
const int LeftAntenna =  11;

// variables will change:
int RightAntennaState = 0;         // variable for reading the pushbutton status
int LeftAntennaState = 0;

void setup() {
  Serial.begin(57600);
  // initialize the pushbutton pin as an input:
  pinMode(RightAntenna, INPUT);
  pinMode(LeftAntenna, INPUT);
}

void loop(){
  // read the state of the pushbutton value:
  RightAntennaState = digitalRead(RightAntenna);
  LeftAntennaState = digitalRead(LeftAntenna);

  Serial.print(RightAntennaState);
  Serial.print(',');
  Serial.println(LeftAntennaState);
  delay(10);
}

April 4, 2012

RoboMagellan Ultrasonic Claw

Filed under: Daily — profmason @ 7:56 pm

For last years robomagellan entry there was a single ultrasonic sensor.  On detecting an obstacle, the robot would STOP, BACKUP while turning, and then resume.  This worked as the bot successfully avoided bushes and even a nasty lamp post during the competition.  However, since robomagellan is a competition about SPEED, this was not an optimal strategy.  This year the top chassis of Robomagellan has been redesigned to reflect a whimsical scorpion theme.  A scorpion has claws and we needed a way to justify attaching claws to the platform…..

Thus the idea of ultrasonic ranging claws was born as shown at right.

The three ultrasonic sensors are connected to an arduino mini which triggers the sensors in sequence and reports the corresponding distances at 8N1 57600 over the attached USB dongle in a comma delimited format at ~20Hz.  IE 300,86,80 would mean that the center and right sensor detect something at 80 cm.

Here is the arduino code:

/*
Ultrasonic input, serial output
Triggers an ultrasonic sensor, Reads the duration pin, and sends to serial port.
Given as a comma delimited triplet L,C,R.  Values greater then 0 are valid.  Values <= 0
mean that no valid input was detected. Max detection range is set by the timeout
on the pulsein command (pulsein timeout * 340 / 2 = range)
IE 17000 us * 340 /2 = 2.89 m
*/

// These constants won't change.  They're used to give names
// to the pins used:
const int S3pingPin = 9;  // Trigger Pin
const int S3inPin = 8; // Echo Pin
const int S2pingPin = 11;  // Trigger Pin
const int S2inPin = 10; // Echo Pin
const int S1pingPin = 7;  // Trigger Pin
const int S1inPin = 6; // Echo Pin

long duration,  cm;

void setup() {
// initialize serial communications at 57600 bps:
Serial.begin(57600);
pinMode(S1pingPin, OUTPUT);
pinMode(S1inPin, INPUT);
pinMode(S2pingPin, OUTPUT);
pinMode(S2inPin, INPUT);
pinMode(S3pingPin, OUTPUT);
pinMode(S3inPin, INPUT);
Serial.println("Starting");
}

void loop() {
digitalWrite(13,HIGH);  //LED Indicator
  // 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:
digitalWrite(S1pingPin, LOW);
delayMicroseconds(2);
digitalWrite(S1pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(S1pingPin, LOW);

duration = pulseIn(S1inPin, HIGH, 17000);
cm = duration / 29 / 2;
// print the results to the serial monitor:
if (cm < 450){
Serial.print(cm);
Serial.print(',');
}
else{
  Serial.print(-cm);
  Serial.print(',');
}
delay(17);
digitalWrite(13,LOW);  //LED Indicator
digitalWrite(S2pingPin, LOW);
delayMicroseconds(2);
digitalWrite(S2pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(S2pingPin, LOW);

duration = pulseIn(S2inPin, HIGH, 17000);
cm = duration / 29 / 2;
// print the results to the serial monitor:
if (cm < 450){
Serial.print(cm);
Serial.print(',');
}
else{
  Serial.print(-cm);
  Serial.print(',');
}
delay(17);
digitalWrite(S3pingPin, LOW);
delayMicroseconds(2);
digitalWrite(S3pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(S3pingPin, LOW);

duration = pulseIn(S3inPin, HIGH, 17000);
cm = duration / 29 / 2;
// print the results to the serial monitor:
if (cm < 450){
Serial.println(cm);
}
else{
  Serial.println(-cm);
}
// wait 10 milliseconds before the next loop
delay(17);
}

March 23, 2012

Arduino Boe-Bot

Filed under: Daily — profmason @ 9:21 pm

Yes the picture at right really is an Arduino Mini in a Basic Stamp2 socket on a Boe-Bot!  Parallax has recently released an Arduino Shield for the Boe-Bot.  This a great idea, as the boe-bot is a nice starter robotics platform and parallax writes some of the best tutorials to get students started in electronics and robotics.  Their approach of focusing on the electronics aspect of robotics is VERY different then taking students through either a Lego or Vex robotics introduction.  I know that LEGO dominates the introductory robotics mind space, but that is a terrible loss engineering since the emphasis is almost entirely on programming (and even that doesn’t teach much in the way of fundamental procedural skills!)  Parallax seems to be run by old electronics folks who think like I do and I have always loved their educational materials, having used their “Robotics with the Boe-Bot” as a starting point for many students.

The Achilles heel of Parallax has been their Basic Stamp and then their Propeller line of chips.  While the Basic Stamp was a fine piece of hardware, it had the students learn …. BASIC… Additionally, the cost per chip was too high to encourage their use in throw away projects. (IE my students burn out an ATMEGA168 or a PICAXE and we throw it away….) At last a solution!   Leverage the great educational materials and design of the parallax boe-bot and develop a shield for the Arduino to allow the use of the Arduino programming environment, libraries and relatively inexpensive hardware.

However, it turns out that you don’t even need an Parallax Boe-Bot shield to get started.  The Arduino Mini plugs directly into the Basic Stamp socket.  You need to connect an external programmer (I used a CPS2102  with reset) to the four pins on the mini programming header.  If you want autoreset, you need to include an inline 0.1 uF capacitor from the DTR line on the programmer to one of the reset pins. (I pushed the pin from the Reset through to the front and attached it there.)

Plug the mini in the BS2 Socket and away you go.  The power switch and reset button work just fine.  The only differences in using the standard board of education with the mini is that the 4 servo jacks on the board are attached to Analog0-3 and the pin number is different (Subtract 2 from each digital pin so that Pin 4 on the Arduino becomes Pin 2 on the boebot.  On their new shield board, they have attached the servos to pins 10-13 instead and straightened out the numbering which is a superior solution!

With these changes all of the sample projects on the Parallax Arduino Boe-Bot website can run:

  1. Each of the BS Pins P0-P11 Correspond to Arduino Pins 2-13
  2. BS Pins P12-P15 Correspond to Arduino Pins A0-A3
  3. So change  servoRight.attach(12); to servoRight.attach(A0);
  4. Change   servoLeft.attach(13); to servoRight.attach(A1);
  5. Make other pin changes as necessary.

Have fun with this.  I hope that parallax write lots more material for this great board and if they do I see lots of these kits in my future!

March 16, 2012

Dual GamePort Joystick to TTL Serial

Filed under: Daily — profmason @ 10:36 pm

Classic gameport joysticks such as the Logitech wingman are excellent controllers to use with small microprocessors since the output is either a varying resistance or a switch.  However a single joystick may have as many as 10 outputs which requires substantial wiring.  In the case of the robosub project it is desired to use a pair of joysticks (in this case 14 IO in total).  Sending 14 signals down a 100 foot tether to the submarine adds significant cabling to the tether.  Instead the 14 IO are converted into a TTL serial signal which is then sent down the cable at 2400 baud.   2400 baud is selected as lower speed means more robust signaling.  If it turns out that this is not sufficiently robust at long cable lengths, we can use a Max232 line driver on each end.

Below is the code for both ends of the project:

/*
Read PC Joystick
A5 Joy1X A4 Joy1Y  A3 Joy1X1 (Hat etc)  A2 Joy1Y1 (Throttle etc)  A1 Joy2X1  A0 Joy2Y1
D2 Joy1Butn1  D3 Joy1Butn2  D4 joy1Butn3  D5 joy1Butn4
D6 Joy2Butn1  D7 Joy2Butn2  D8 Joy2Butn3  D9 Joy2Butn4</code>

Note on Box: Green - Green&amp;White +5 Orange RX Orange&White TX

Functions:
read_joysticks:  Read the current state of the joysticks
read_data:  Read joystick data from another arduino using this code
write_data:  Write joystick data to the serial port
debug_vals:  Output the valiables in human readable form

Sample Python Testcode at end

*/

// These constants won't change.  They're used to give names
// to the pins used:
const int Joy1X = A5;
const int Joy1Y = A4 ;
const int Joy1X1 =  A3;// (Hat etc)
const int  Joy1Y1 = A2; // (Throttle etc)
const int  Joy2X = A1;
const int  Joy2Y = A0;
const int  Joy1Butn1 = 2;
const int  Joy1Butn2 =3;
const int  Joy1Butn3 = 4;
const int  Joy1Butn4 = 5;
const int  Joy2Butn1 = 6;
const int  Joy2Butn2 = 7;
const int  Joy2Butn3 = 8;
const int  Joy2Butn4 = 9;

//Define a set of variables to store the values.
int Joy1X_Val,Joy1Y_Val,Joy1X1_Val,Joy1Y1_Val,Joy2X_Val,Joy2Y_Val;
int Joy1Butn1_Val,Joy1Butn2_Val,Joy1Butn3_Val,Joy1Butn4_Val,Joy2Butn1_Val, Joy2Butn2_Val,Joy2Butn3_Val,Joy2Butn4_Val;

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(2400);
pinMode(Joy1Butn1, INPUT);
pinMode(Joy1Butn2, INPUT);
pinMode(Joy1Butn3, INPUT);
pinMode(Joy1Butn4, INPUT);
pinMode(Joy2Butn1, INPUT);
pinMode(Joy2Butn2, INPUT);
pinMode(Joy2Butn3, INPUT);
pinMode(Joy2Butn4, INPUT);
Serial.println('Initialized');
}

void loop() {
//Standard usage for reading joysticks
read_joysticks();
write_data();
//Standard usage for getting data from the joystick module
//read_data();  //this makes the data available in the global
//joystick variables declared above
delay(60);  // wait 60 milliseconds before the next loop
}

void read_joysticks()
{
Joy1X_Val = map(analogRead(Joy1X), 0, 1023, 0, 255);
Joy1Butn1_Val =  digitalRead(Joy1Butn1);
Joy1Y_Val = map(analogRead(Joy1Y), 0, 1023, 0, 255);
Joy1Butn2_Val =  digitalRead(Joy1Butn2);
Joy1X1_Val = map(analogRead(Joy1X1), 0, 1023, 0, 255);
Joy1Butn3_Val =  digitalRead(Joy1Butn3);
Joy1Y1_Val = map(analogRead(Joy1Y1), 0, 1023, 0, 255);
Joy1Butn4_Val =  digitalRead(Joy1Butn4);

Joy2X_Val = map(analogRead(Joy2X), 0, 1023, 0, 255);
Joy2Butn1_Val =  digitalRead(Joy2Butn1);
Joy2Y_Val = map(analogRead(Joy2Y), 0, 1023, 0, 255);
Joy2Butn2_Val =  digitalRead(Joy2Butn2);
Joy2Butn3_Val =  digitalRead(Joy2Butn3);
Joy2Butn4_Val =  digitalRead(Joy2Butn4);
}

void read_data()
{
if (Serial.available() > 0) // Don't read unless
// there you know there is data
{
while(Serial.read() != '&')//Check for the Start Character
{
}
// read the Values in from the serial port
Joy1X_Val = Serial.read();
Joy1Y_Val =  Serial.read();
Joy1X1_Val =  Serial.read();
Joy1Y1_Val = Serial.read();
Joy1Butn1_Val =  Serial.read();
Joy1Butn2_Val = Serial.read();
Joy1Butn3_Val = Serial.read();
Joy1Butn4_Val =  Serial.read();

Joy2X_Val = Serial.read();
Joy2Y_Val =  Serial.read();
Joy2Butn1_Val =  Serial.read();
Joy2Butn2_Val = Serial.read();
Joy2Butn3_Val = Serial.read();
Joy2Butn4_Val =  Serial.read();
}
}

void write_data()
{
Serial.print('&');
Serial.write(Joy1X_Val);
Serial.write(Joy1Y_Val);
Serial.write(Joy1X1_Val);
Serial.write(Joy1Y1_Val);
Serial.write(Joy1Butn1_Val);
Serial.write(Joy1Butn2_Val);
Serial.write(Joy1Butn3_Val);
Serial.write(Joy1Butn4_Val);
Serial.write(Joy2X_Val);
Serial.write(Joy2Y_Val);
Serial.write(Joy2Butn1_Val);
Serial.write(Joy2Butn2_Val);
Serial.write(Joy2Butn3_Val);
Serial.write(Joy2Butn4_Val);
Serial.println();
}

void debug_vals()
{
Serial.print('['); //This is the start character in the message
Serial.print(Joy1X_Val,HEX);
Serial.print(Joy1Y_Val,HEX);
Serial.print(Joy1X1_Val,HEX);
Serial.print(Joy1Y1_Val,HEX);
Serial.print(Joy1Butn1_Val,BIN);
Serial.print(Joy1Butn2_Val,BIN);
Serial.print(Joy1Butn2_Val,BIN);
Serial.print(Joy1Butn2_Val,BIN);
Serial.print(Joy2X_Val,HEX);
Serial.print(Joy2Y_Val,HEX);
Serial.print(Joy2Butn1_Val,BIN);
Serial.print(Joy2Butn2_Val,BIN);
Serial.print(Joy2Butn2_Val,BIN);
Serial.print(Joy2Butn2_Val,BIN);
Serial.println(']');//Terminating Character
}
/*  Python code to read in Data
import serial  #The pyserial library must be installed
#Format
#&,Joy1X,Joy1Y,Joy1X1,Joy1Y1,Joy1Btn1,Joy1Btn2,Joy1Brn3,Joy1Btn4,Joy2X,Joy2Y,Joy2Btn1,Joy2Btn2,Joy2Btn3,Joy2Btn4

ser = serial.Serial(13,2400)  #By default the device uses port 14 (python #s from 0)
print ser.portstr #Print the valid port

j=0
while (j < 100):  #100 for testing
char = ser.read()  #Read in a character
if char == '&': #If we are at the start of a new string
commandlist = [] #initialize the list
for i in range(0,14):
char = ser.read()
commandlist.append(ord(char)) #Append the ascii value to the list
i += 1
print commandlist  #Print the list after it is built
j+=1

ser.close()
*/
Older Posts »

Powered by WordPress