I am working on a robotic arm that has six servos which is being controlled by an arduino uno. The servos are analog servos from adafruit and they are special in the sense that you can get feedback from the servos, i.e their actual position after you told it where to go. What I am working on is trying to adapt this example code to include six servos instead of one. https://github.com/adafruit/Feedback-Servo-Record-and-Play/blob/master/servo_recordplay.ino
Here is my code so far and its errors
// Example code for recording and playing back servo motion with a
// analog feedback servo
// http://www.adafruit.com/products/1404
#include <Servo.h>
#include <EEPROM.h>
#define CALIB_MAX 512
#define CALIB_MIN 100
#define SAMPLE_DELAY 25 // in ms, 50ms seems good
uint8_t recordButtonPin = 12;
uint8_t playButtonPin = 7;
uint8_t servo1Pin = 9;
uint8_t servo2Pin = 10;
uint8_t servo1FeedbackPin = A0;
uint8_t servo2FeedbackPin = A1;
uint8_t servo3FeedbackPin = A2;
uint8_t servo4FeedbackPin = A3;
uint8_t servo5FeedbackPin = A4;
uint8_t servo6FeedbackPin = A5;
uint8_t ledPin = 13;
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
void setup() {
Serial.begin(9600);
pinMode(recordButtonPin, INPUT);
digitalWrite(recordButtonPin, HIGH);
pinMode(playButtonPin, INPUT);
digitalWrite(playButtonPin, HIGH);
pinMode(ledPin, OUTPUT);
Serial.println("Servo RecordPlay");
}
void loop() {
if (! digitalRead(recordButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(recordButtonPin));
delay(20);
// OK released!
recordAllServos(servo1Pin, servo1FeedbackPin, recordButtonPin);
}
if (! digitalRead(playButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(playButtonPin));
delay(20);
// OK released!
playAllServo(servo1Pin, playButtonPin);
}
}
void playAllServo(uint8_t servoPin, uint8_t buttonPin) {
uint16_t addr = 0;
Serial.println("Playing");
servo1.attach(servo1Pin);
while (digitalRead(buttonPin)) {
uint8_t x = EEPROM.read(addr);
Serial.print("Read EE: "); Serial.print(x);
if (x == 255) break;
// map to 0-180 degrees
x = map(x, 0, 254, 0, 180);
Serial.print(" -> "); Serial.println(x);
servo1.write(x);
delay(SAMPLE_DELAY);
addr++;
if (addr == 512) break;
}
Serial.println("Done");
servo1.detach();
delay(250);
}
void recordAllServos(uint8_t servoPin, uint8_t buttonPin) {
uint16_t addr = 0;
Serial.println("Recording");
digitalWrite(ledPin, HIGH);
pinMode(servo1FeedbackPin, INPUT);
pinMode(servo2FeedbackPin, INPUT);
pinMode(servo3FeedbackPin, INPUT);
pinMode(servo4FeedbackPin, INPUT);
pinMode(servo5FeedbackPin, INPUT);
pinMode(servo6FeedbackPin, INPUT);
while (digitalRead(buttonPin))
{
readServo(servo1FeedbackPin);
readServo(servo2FeedbackPin);
readServo(servo3FeedbackPin);
readServo(servo4FeedbackPin);
readServo(servo5FeedbackPin);
readServo(servo6FeedbackPin);
if (addr > 506) break;
delay(SAMPLE_DELAY);
}
if (addr != 1024) EEPROM.write(addr, 255);
digitalWrite(ledPin, LOW);
Serial.println("Done");
delay(250);
}
void readAllServo(uint8_t analogPin)
{
uint16_t a = analogRead(analogPin);
Serial.print("Read analog pin "); Serial.print(analogPin); Serial.print(": ");
Serial.print(a);
if (a < CALIB_MIN) a = CALIB_MIN;
if (a > CALIB_MAX) a = CALIB_MAX;
a = map(a, CALIB_MIN, CALIB_MAX, 0, 254);
Serial.print(" -> "); Serial.println(a);
EEPROM.write(addr, a);
addr++;
}
The errors that I am getting from the arduino ide are
Teachable_Arm_Mark.cpp: In function 'void loop()':
Teachable_Arm_Mark:10: error: too many arguments to function 'void recordAllServos(uint8_t, uint8_t)'
Teachable_Arm_Mark:49: error: at this point in file
Teachable_Arm_Mark.cpp: In function 'void recordAllServos(uint8_t, uint8_t)':
Teachable_Arm_Mark:100: error: 'readServo' was not declared in this scope
Teachable_Arm_Mark.cpp: In function 'void readAllServo(uint8_t)':
Teachable_Arm_Mark:127: error: 'addr' was not declared in this scope
Any help much appreciated
Thanks
In void loop you have
recordAllServos(servo1Pin, servo1FeedbackPin, recordButtonPin);
but recordAllServos is declared as
void recordAllServos(uint8_t servoPin, uint8_t buttonPin)
Hence too many arguments 3 vs 2...
Related
I have an arduino with 3 sensors connected and need to send the information I'm getting from the said sensors to another arduino and have it displayed on a connected lcd. I tried to go about this by changing the float values I'm getting into a string, sending the string to the other arduino and displaying that on the lcd. But when I try to execute this, I get an error saying :
" In function 'void receiveEvent(int)':
16:24: error: incompatible types in assignment of int to char [7] "
#include <Wire.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int sensePin = A0;
int sensorInput;
int lightPin = A1;
int lightInput;
int gasPin = A2;
int gasInput;
int buzzer = 13;
int b_state = 3;
float temp;
float light;
char t_buffer[7];
int state = 0;
void setup()
{
Wire.begin();
pinMode(A0, INPUT);
pinMode(A1,INPUT);
pinMode(buzzer, OUTPUT);
pinMode(A2, INPUT);
pinMode(buzzer, OUTPUT);
pinMode(b_state, INPUT_PULLUP);
Serial.begin(9600);
lcd.begin(16, 2);
attachInterrupt(digitalPinToInterrupt(3), buttons, FALLING);
}
void loop()
{
gasInput = analogRead(gasPin);
sensorInput = analogRead(sensePin);
lightInput = analogRead(lightPin);
temp = (float)sensorInput / 1024;
temp = temp * 5;
temp = temp - 0.498;
temp = temp * 100;
light = ((float)lightInput - 26) / 8.97;
dtostrf(temp, 6, 2, t_buffer);
Serial.print("Current Temperature: ");
Serial.println(temp);
Serial.print("Current Light: ");
Serial.println(light);
Serial.print("Gas (conc.?): ");
Serial.println(gasInput);
Wire.beginTransmission(9);
Wire.write(t_buffer, 7);
Wire.endTransmission();
delay(100);
if (state == 0){
lcd.setCursor(0, 0);
lcd.print("Temp (C): ");
lcd.setCursor(0,1);
lcd.print(t_buffer);
}
else {
lcd.setCursor(0,0);
lcd.print("Light Intensity: ");
lcd.setCursor (0,1);
lcd.print(light);
}
if (gasInput > 800)
digitalWrite(buzzer, HIGH);
else
digitalWrite(buzzer, LOW);
}
void buttons()
{
lcd.clear();
state = !state;
}
#include <Wire.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
float temp;
char t_buffer[7];
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
Wire.begin(9);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int bytes) {
t_buffer = Wire.read();
//temp = t_buffer.toFloat();
}
void loop() {
lcd.setCursor(0, 0);
lcd.print("Temp (C): ");
lcd.setCursor(0,1);
lcd.print(t_buffer);
}
Also I have 2 separate float values that I need to send and I'm thinking I could time the transmissions properly and send them both one after the other. Is this a good way of doing this or is there an alternative way?
The circuit
This may not be a direct answer to your question but it may help you figure it out.
t_buffer is a pointer, while t_buffer[0] is the first character in your buffer. The Wire.read returns a char and not a pointer.
If the explanation above does not make sense you may want to read on arrays.
Having said that, since you main loop is almost empty you can use the suggestion by Juraj and use Wire.readBytes(t_buffer , bytes) this way you do not have to worry about indexing through the buffer.
I would strongly suggest that you put text data in t_buffer and test your application before trying to send a float.
I'm trying to make an smart car with Arduino Mega, and I need to turn both of the back wheels on for an specific time sometimes. I've been told that I can set a "digital HIGH" time using tone, But as I need them to work in a same time, Is there a way to set tone for two pins in one line or something to do instead?
Thanks for your help.
#include <Servo.h>
/////////////////////
Servo servo;
/////////////////////
int trig = 12;
int echo = 13;
long duration;
int distance;
int dist_right;
int dist_left;
int ang = 90;
unsigned int value = 255;
unsigned long tone_time = 3000;
float forward_time;
/////////////////////
int ena = 35;
int in1 = 7;
int in2 = 6;
int in3 = 5;
int in4 = 4;
int enb = 47;
/////////////////////
void setup()
{
Serial.begin(9600);
servo.attach(22);
pinMode(trig, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(ena, OUTPUT);
pinMode(enb, OUTPUT);
pinMode(echo, INPUT);
digitalWrite(ena, HIGH);
digitalWrite(enb, HIGH);
}
void loop() {
servo.write(90);
distance = dist();
if(distance<=15)
{
for(ang;ang>=0;ang-=2)
{
servo.write(ang);
delay(30);
}
dist_right = dist();
Serial.println(dist_right);
for(ang;ang<=180;ang+=2)
{
servo.write(ang);
delay(30);
}
dist_left = dist();
Serial.println(dist_left);
for(ang;ang>=90;ang-=2)
{
servo.write(ang);
delay(30);
}
if(dist_right>=dist_left)
{
tone(in3, value, tone_time);
}
else if(dist_right<dist_left)
{
tone(in1, value, tone_time);
}
servo.write(90);
ang=90;
}
else{
forward_time=distance/25;
tone((in1,in3), value, forward_time);
}
}
int dist(){
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH);
distance= duration*0.034/2;
return distance;
}
I'm 99.99% sure, that your motors will not feel the time differencce if you turn them one by one. Try simplest case and you will see.
// Define your wheel control pins (use same as in your mega)
const int motor1Pin = 5;
const int motor1Pin = 6;
// somewhere in setup method
outputMode(motor1Pin, OUTPUT);
outputMode(motor2Pin, OUTPUT);
// Create function to turn motors and remember the time
unsigned long turnMotorsOn(int seconds) {
// turn motors ant return time when they should be stopped
return millis() + seconds * 1000;
}
// In you code check if it is time to turn off
if (millis() > timeWhenTurnMotorsOff) {
// turn them off
}
Hello i have problem :
state sensor = sensor steps "IF" anyone "steps now = impulse " = all code run"perfect good work im happy" but if sensor LOW a did not detect any motion while loading the code = broke stop all , even if it is at the end close or halfway, it will stop when there is no traffic "" (stage_sensor == HIGH)"", i dont have idea how to fix this//
Please help or sugestion
EDIT : There may be syntax errors (is not consistent), but just wanted to present a problem, the system only works under "if" and this is problem, i dont know how to fix
#include <AccelStepper.h> //accelstepper library
// #define light
// #define move_sensor
// #define pump_water
// #define fan_blowing
// #define fan_extractor
// #define blue
// #define red
// #define green
const byte limitSwitch_1 = 26;
const byte limitSwitch_2 = 25;
bool switchFlipped = false;
bool previousFlip = true;
int switchCounter;
int newSpeed;
int state_sensor = 0; // <--- stage sensor //
int light = 2;
int blue = 3;
int red = 4;
int green = 5;
int fan_blowing = 6;
int water_pump = 8;
int move_sensor = 9;
int fan_extractor = 10;
AccelStepper stepper(1, 22, 23);
void setup()
{
pinMode(water_pump, OUTPUT);
pinMode(light, OUTPUT);
pinMode(fan_blowing, OUTPUT);
pinMode(fan_extractor, OUTPUT);
pinMode(blue, OUTPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(move_sensor, INPUT);
pinMode(limitSwitch_1, INPUT_PULLUP); //pin 1 engine (IF touch)
pinMode(limitSwitch_2, INPUT_PULLUP); //pin 2 engine (IF touch)
Serial.begin(9600);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
stepper.setSpeed(1000);
delay(500);
}
void loop()
{
digitalWrite(light, HIGH);
digitalWrite(blue, HIGH);
state_sensor = digitalRead(sensor_move);
if (state_sensor == HIGH) // <--- stage sensor IF anyone move = all code run but if sensor LOW did not detect movement all code broke stop all //
{
digitalWrite(blue, LOW);
digitalWrite(red, HIGH);
stepper.runSpeed();
engine();
}
}
void engine()
{
if(digitalRead(limitSwitch_1) == LOW)
{
switchCounter++;
delay(1000);
newSpeed = -1 * (1000 + (switchCounter * 200));
stepper.setSpeed(newSpeed);
}
if(digitalRead(limitSwitch_2) == LOW)
{
switchCounter++;
delay(1000);
newSpeed = -1 * (1000 + (switchCounter * 200));
stepper.stop();
fans();
}
}
void fans()
{
digitalWrite(red, HIGH);
{
digitalWrite(fan_blowing, HIGH);
digitalWrite(fan_extractor, HIGH);
delay(1000);
digitalWrite(water_pump, HIGH);
}
delay(1000);
digitalWrite(red, LOW);
digitalWrite(water_pump, LOW);
digitalWrite(green, HIGH);
delay(1000);
digitalWrite(fan_blowing, LOW);
digitalWrite(fan_extractor, LOW);
digitalWrite(green, LOW);
digitalWrite(blue, HIGH); //this blue RGB light "ON" but if sensor_steps "ON" = active cycle , blue light led off
delay(1000);
}
What you could do is set up a global "stage" variable:
#include <AccelStepper.h> //accelstepper library
const byte limitSwitch_1 = 26;
const byte limitSwitch_2 = 25;
bool switchFlipped = false;
bool previousFlip = true;
int switchCounter;
int newSpeed;
int stage;
AccelStepper stepper(1, 22, 23);
void setup()
{
pinMode(limitSwitch_1, INPUT_PULLUP);
pinMode(limitSwitch_2, INPUT_PULLUP);
Serial.begin(9600);
stepper.setMaxSpeed(1000);
stepper.setAcceleration(100);
stepper.setSpeed(1000);
delay(500);
stage = 0;
}
void loop()
{
stepper.runSpeed();
runner();
}
void runner()
{
if(stage == 0 && digitalRead(limitSwitch_1) == LOW)
{
switchCounter++;
delay(5000);
newSpeed = -1 * (1000 + (switchCounter * 200));
stepper.setSpeed(newSpeed);
++stage;
}
if(stage == 1 && digitalRead(limitSwitch_2) == LOW)
{
stepper.setSpeed(1000);
delay(1000);
stepper.setSpeed(0);
++stage;
}
if (stage == 2) {
// do next thing, then ++stage;, etc.
}
}
I am trying to get voltage values from my master to my slave but only the voltage from Pin3 is being sent over and not my values from pin 4. I am new to coding so please make your solution very "jargon-less." If you could provide me with an example then it will be greatly appreciated.
MASTER CODE:
void pin3() {
Wire.beginTransmission(0x08);
int val2 = analogRead(twosensorpin);
float volts2 = (val2 / 1023.0) * refvoltage;
voltage = String(volts2);
char volt2[5];
voltage.toCharArray(volt2, 5);
Serial.print("The voltage are pin 2 is ");
Serial.println(voltage);
Wire.write(volt2);
Wire.endTransmission();
}
void pin4() {
Wire.beginTransmission(0x08);
int val3 = analogRead(threesensorpin);
float volts3 = (val3 / 1023.0) * refvoltage;
voltage2 = String(volts3);
char volt3[5];
voltage.toCharArray(volt3, 5);
Serial.print("The voltage are pin 3 is ");
Serial.println(voltage2);
Wire.write(volt3);
Wire.endTransmission();
}
SLAVE CODE:
#include <Wire.h>
#define SLAVE_ADDRESS 0X08
String q;
String r = "3.20";
// name the motor control pins
#define PWMa 7
#define PWMb 5
#define PWMc 8
#define PWMd 6
void setup() {
// configure the motor control pins as outputs
pinMode(PWMa, OUTPUT);
pinMode(PWMb, OUTPUT);
pinMode(PWMc, OUTPUT);
pinMode(PWMd, OUTPUT);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
//Wire.onRequest(requestEvent);
Serial.begin(9600);
}
void loop() {}
void receiveEvent() {
q = "";
while (Wire.available()) {
char c = Wire.read();
q += c;
}
do {
if (q < r) {
Serial.print("The value coming from pin 2 is ");
Serial.println(q);
digitalWrite(PWMa, LOW);
digitalWrite(PWMb, HIGH);
digitalWrite(PWMc, LOW);
digitalWrite(PWMd, HIGH);
//delay(500);
}
} while (Wire.available());
do {
if (q > r) {
digitalWrite(PWMa, HIGH);
digitalWrite(PWMb, LOW);
digitalWrite(PWMc, HIGH);
digitalWrite(PWMd, LOW);
}
} while (Wire.available());
As Edd said you should show us some output.
But assuming you're trying to compare the incoming data to 3.20 as a numerical value, the following code will do the job.
Master
float send_i2c(int val){
float volts = (val / 1023.0) * refvoltage;
char v[5];
String(volts).toCharArray(v, 5);
Wire.beginTransmission(0x08);
Wire.write(v);
Wire.endTransmission();
return volts;
}
void pin3(){
Serial.println("Pin3 val : " + String(send_i2c(analogRead(twosensorpin))));
}
void pin4(){
Serial.println("Pin4 val : " + String(send_i2c(analogRead(threesensorpin))));
}
Slave
#include <Wire.h>
#define SLAVE_ADDRESS 0X08
#define R 3.20
String q;
// name the motor control pins
#define PWMa 7
#define PWMb 5
#define PWMc 8
#define PWMd 6
void setup() {
// configure the motor control pins as outputs
pinMode(PWMa, OUTPUT);
pinMode(PWMb, OUTPUT);
pinMode(PWMc, OUTPUT);
pinMode(PWMd, OUTPUT);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
}
void loop() {}
void receiveEvent(int a) {
int num = 0;
while (Wire.available())
q += Wire.read();
num = q.toInt();
Serial.print("The value: ");
Serial.println(q);
digitalWrite(PWMa, (num < R) ? LOW : HIGH);
digitalWrite(PWMb, (num < R) ? HIGH : LOW);
digitalWrite(PWMc, (num < R) ? LOW : HIGH);
digitalWrite(PWMd, (num < R) ? HIGH : LOW);
q = "";
}
But again you should consider your way of controlling your GPIO outputs.
You've done quite a lot of mistakes. Check this page to get more idea about Strings. And this page for Wire transmission.
I am building an Arduino car, which avoids obstacles and when I try to upload the code to my Arduino from the PlatformIO package of Atom I get an error message like this:
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0aaa
0x68 != 0x60
avrdude: verification error; content mismatch
avrdude done. Thank you.
This started happening a few days ago for no reason. It worked perfectly and suddenly I started getting this error message.
My code is:
#include <Arduino.h>
#include <Servo.h>
const int trigPin = 6;
const int echoPin = 7;
const int motorRF = 3;
const int sleep = 4;
const int motorRB = 9;
const int motorLF = 10;
const int motorLB = 11;
int minDistance = 350;
long value;
int speed = 1000;
int randNum;
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motorRF, OUTPUT);
pinMode(motorRB, OUTPUT);
pinMode(motorLF, OUTPUT);
pinMode(motorLB, OUTPUT);
pinMode(sleep, OUTPUT);
Serial.begin(9600);
}
//Define the directions of the motors
void forward() {
analogWrite(motorRF, speed);
analogWrite(motorLF, speed);
analogWrite(motorRB, 0);
analogWrite(motorLB, 0);
}
void backward() {
analogWrite(motorRF, 0);
analogWrite(motorLF, 0);
analogWrite(motorRB, speed);
analogWrite(motorLB, speed);
}
void right() {
analogWrite(motorRF, 0);
analogWrite(motorLF, speed);
analogWrite(motorRB, speed);
analogWrite(motorLB, 0);
}
void left() {
analogWrite(motorRF, speed);
analogWrite(motorLF, 0);
analogWrite(motorRB, 0);
analogWrite(motorLB, speed);
}
void loop() {
//Ultrasonic sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
value = pulseIn(echoPin, HIGH);
Serial.println("Value = "); Serial.println(value);
delay(50);
//Motors
digitalWrite(sleep, HIGH);
if(value > minDistance) {
//Drive forward
backward();
}
else {
//Drive backward
forward();
delay(1000);
//Pick between number 1 and 2
randNum = random(0, 2);
Serial.println("Random Num = "); Serial.println(randNum);
//If the number is 2 then drive right
if(randNum == 1) {
right();
delay(500);
}
//Else drive left
else {
left();
delay(500);
}
}
}
Thank you.
It is a hardware problem. The program is fine. I tried to upload it to another Arduino and it worked perfectly. Thank you.