Controlling A Robotic Arm With Potentiometers
Hello all, I am working on an arm made of potentiometers that, when moved, will wirelessly move another arm made of servos. You can see what I'm talking about in this video at about the halfway point. . I'm going to use two Parallax Activity Boards and two XBees to control 5 servos and 1 linear actuator using potentiometers. I have already controlled a servo with a potentiometer on an activity board. I tried controlling two servos with two potentiometers on an Activity Board, but one potentiometer moved both servos and the other potentiometer didn't do anything. Just to be clear I am using Propeller C. I am also having trouble figuring out how to wirelessly control a servo using the Xbees. Thank you so much for reading, and any help is appreciated.
Comments
The way you translate the potentiometer position into a servo value will be important.
Tom
Jim
There's a great little ADC called the MCP3208, 8 channels and 12 bit resolution. Here's a thread on getting it working with PropC - http://forums.parallax.com/discussion/141893/spi-mcp3208-in-c
If you can get away with only 4 channels, as mentioned post your code and setup, it sounds like you're very close on reading the ADC/pots, let's get that going and then work on the XBee part.
Which XBee radios do you have?
At first I was using the "YouTube" link to add the URL but it was't working. Just pasting the raw link without any tags did the trick.
I tried using the code that was given in that thread, and while there were no errors it didn't work.
Here is my code for trying to control a servo with the MCP 3208 on the Activity Board (not wireless)
#include "simpletools.h"
#include "abvolts.h"
#include "servo.h"
//Set these parameters to the pins where your ADC chip is plugged in
#define ADC_CLK 15
#define ADC_DO 14
#define ADC_DI 13
#define ADC_CS 12
#define ADC_AVERAGE 1
//ADC Channels - Do not change these numbers or reading from the ADC chip will not work
#define CHANNEL_1 24
#define CHANNEL_2 25
#define CHANNEL_3 26
#define CHANNEL_4 27
#define CHANNEL_5 28
#define CHANNEL_6 29
#define CHANNEL_7 30
#define CHANNEL_8 31
//This function returns a value from the ADC chip. The value returned is between is 0 - 4096
//Use the channel constants to call this function
double readADCVal(int channel);
double readADCVal(int channel);
double readADCVal(int channel);
double readADCVal(int channel);
//code for function
double readADCVal(int channel)
{
double adcVal;
double tempAdcVal = 0;
for (int x = 0; x < ADC_AVERAGE; x++)
{
low(ADC_CS); //Turn ADC chip on
shift_out(ADC_DI, ADC_CLK, MSBFIRST, 5, channel); //Select channel
tempAdcVal += shift_in(ADC_DO, ADC_CLK, MSBPOST, 13); //Read value
high(ADC_CS); //Turn ADC chip off
low(ADC_CLK); //Stop giving clock signals
pause(1);
}
adcVal = tempAdcVal / ADC_AVERAGE;
return adcVal;
}
int main() // Main function
{
print("Twist knob to control servo.");
while(1)
{
double x = readADCVal(1);//ad_in(7);
print("%f", x);
double y = x * 1800 / 2703;
servo_angle(14, y);
// x = ad_in(2);
//y = x * 1800 / 2703;
//servo_angle(15, y);
//x = ad_in(1);
//y = x * 1800 / 2703;
//servo_angle(16, y);
//x = ad_in(0);
//y = x * 1800 / 2703;
//servo_angle(17, y);
}
}
The values that the servo function uses are integers (0 to 1800).
Did print("%f", x); print out a reasonable number? Try printing y to make sure it is between 0 and 1800.
My mind is slow right now, but where did 2703 come from?
Tom
Be sure to power the activity board with a battery pack; the usb port can't power the servos. Also be sure to turn on the Activity board to the second on position.
The 2703 in the book is because the voltage being read was 3.3v max. If you set VDD and Vref to 5 v you should use 4096. (2703 = 3.3 * 4096/5)
As a demo, this works. But the motion is not smooth, so the delays need work, and the limits on the servos need to be set for your servos.
I'm not sure why your program didn't work, because I only made a few tweeks.
Tom
The first thing I would try is having the program on the sending A-board just create a bunch of 16 bit words (or you could just enter some values from the terminal and store them as words), then break into 8 bit bytes, send to the receiving A-board, recombine them, and print them. You want to make sure that they are the same values that you typed.
Tom
"channel" in the function is being set to the number 1.
But the value being sent to the mcp3208 in the function statement: should not be just the channel number. It needs to be a 5 bit command value that includes the mode and channel number. Those are the numbers in the #define section. The full 5 bit number for channel 1 is 24 (0b11000). Note what we are calling channel 1 is actually channel 0 since the 3208 channels are numbered 0 -7.
So you have to call the function
Tom