Buongiorno a tutti!
volevo porvi alcuni quesiti:
-il codice che posterò controlla una base mobile (4 ruote)
-effettua ad ogni comando una lettura di distanza con un HC-SR04
la mia domanda è: riesco a fargli leggere la distanza con l'ostacolo ogni secondo per esempio?
Questo è il mio codice:
#include <NewPing.h>
#include <AFMotor.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#define PingPin A0
NewPing sonar(PingPin,PingPin);
const int speed = 20; //velocità in %
#define RX 15 //A1
#define TX 16 //A2
#define Led 17 //A3
#define FotoR 18//A4
int data;
int data2;
Servo servo;
AF_DCMotor Motor_Left_Front(4,MOTOR34_1KHZ);
AF_DCMotor Motor_Right_Front(3,MOTOR34_1KHZ);
AF_DCMotor Motor_Left_Rear(1,MOTOR12_1KHZ);
AF_DCMotor Motor_Right_Rear(2,MOTOR12_1KHZ);
SoftwareSerial btSerial(RX,TX);
void setup() {
Serial.begin(9600);
btSerial.begin(9600);
servo.attach(9);
servo.write(45);
pinMode(Led,OUTPUT);
pinMode(FotoR,INPUT);
Motor_Left_Front.setSpeed(255);
Motor_Right_Front.setSpeed(255);
Motor_Left_Rear.setSpeed(255);
Motor_Right_Rear.setSpeed(255);
}
void loop() {
if(btSerial.available())
{
data2=btSerial.read();
Serial.print(data2);
//data=Serial.read();
Serial.print(data2, HEX);
Serial.print(" - ");
Serial.println((char) data2);
switch(data2)
{
case '0'://Reset servo position
servo.write(45);
break;
case '1'://Look right
servo.write(90);
break;
case '2'://Look left
servo.write(-90);
break;
case '3': //ServoMotor and Distance (HC-SR04)
ServoRotation();
break;
case 'D': //Distance (HC-SR04)
Distance();
break;
case 'O': //Led OFF
btSerial.print("Led OFF");
btSerial.print("");
digitalWrite(Led,LOW);
break;
case 'N': //Led ON
btSerial.print("Led ON");
btSerial.print("");
digitalWrite(Led,HIGH);
break;
case 'F': //Forward
btSerial.print("FORWARD");
btSerial.print("");
Motor_Left_Front.run(FORWARD);
Motor_Right_Front.run(FORWARD);
Motor_Left_Rear.run(FORWARD);
Motor_Right_Rear.run(FORWARD);
ServoRotation();
break;
case 'B': //Backward
btSerial.print("BACKWARD");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(BACKWARD);
Motor_Right_Rear.run(BACKWARD);
break;
case 'S': //Stop
btSerial.print("STOP");
btSerial.print("");
Motor_Left_Front.run(RELEASE);
Motor_Right_Front.run(RELEASE);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(RELEASE);
break;
case 'R': //Turn Right
btSerial.print("Turn Right");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(BACKWARD );
break;
case 'L': //Turn Left
btSerial.print("Turn Left");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(BACKWARD);
Motor_Right_Rear.run(RELEASE );
break;
case 'A': //Auto light
Light();
break;
}
}
}
void ServoRotation()
{
//senso orario
servo.write(0);
delay(300);
servo.write(45);
Distance();
delay(300);
servo.write(90);
delay(300);
//anti-orario
servo.write(135);
delay(300);
servo.write(90);
delay(300);
servo.write(45);
Distance();
delay(300);
}
void Distance()
{
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
btSerial.print("Distance: ");
btSerial.print(uS/US_ROUNDTRIP_CM); // convert time into distance
btSerial.println("cm");
btSerial.print("");
if(uS/US_ROUNDTRIP_CM<10)
{
Motor_Left_Front.run(RELEASE);
Motor_Right_Front.run(RELEASE);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(RELEASE);
}
}
void Light()
{
int luce=analogRead(FotoR);
btSerial.println("Light: "+ String(luce));
if(luce<200)
{
digitalWrite(Led,HIGH);
}
else
{
digitalWrite(Led,LOW);
}
}
Grazie per la disponibilità e l'aiuto!
PS: Mi scuso con il sig. Gugliemo. Ieri non è stata una bella giornata e sono stato molto sgarbato causa problemi personali..
LucaAlba98:
Mi scuso con il sig. Gugliemo. Ieri non è stata una bella giornata e sono stato molto sgarbato causa problemi personali..
Nessun problema, le "brutte giornate", purtroppo, capitano a tutti ...
Riguardo il codice, purtroppo ci devi mettere pesantemente le mani e ... eliminare quelle raffiche di delay() che, ogni volta che chiami la ServoRotation() ... ti BLOCCANO il programma per parecchio tempo tra una chiamata a Distance() ed un altra ...
Per avere un esatto controllo delle temporizzazioni e non avere ritardi, devi NON usare la delay() ed usare la millis() ...
... se non l'hai mai usata/studiata, puoi cominciare a leggere prima QUI, poi QUI ed infine leggi anche QUI e QUI ... vedrai che ti sarà tutto più chiaro.
La ringrazio molto! oggi mi leggerò bene tutto... comunque lei dice che se sostituisco delay con millis potrò far leggere al sensore la distanza in ogni momento? e quando io invierò una lettera dello switch cosa succederà??
io la lettura della distanza la vorrei in QUALSIASI momento...
In pratica, usando la funzine millis(), che NON è bloccante, sei tu che gestisci i "tempi" in cui avvengono le varie cose ...
... immagina una specie di "scheduler" che schedula, ogni N millesimi di secondo (... anche con vari N relativi a ciascun evento) cosa va fatto.
Ovviamnete all'inizio sembra complesso, ma se ci si prende la mano, il loop() diventa solo un posto dove si controllano le "scadenze temporali" e si richiamano le dovute funzioni.
Ritorno su questa discussione.. ho inserito la funzione millis nel codice ma ho un grosso problema.. la lettura me la effettua ogni secondo come da me richiesto ma quando invio un comando (tranne l'accensione e lo spegnimento del led) lui non me lo svolge... quale può essere il problema?
Questo il nuovo codice:
#include <NewPing.h>
#include <AFMotor.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#define PingPin A0
NewPing sonar(PingPin,PingPin);
unsigned long previousMillis = 0;
unsigned long interval=1000;
const int speed = 20; //velocità in %
#define RX 15 //A1
#define TX 16 //A2
#define Led 17 //A3
int data;
int data2;
Servo servo;
AF_DCMotor Motor_Left_Front(4,MOTOR34_1KHZ);
AF_DCMotor Motor_Right_Front(3,MOTOR34_1KHZ);
AF_DCMotor Motor_Left_Rear(1,MOTOR12_1KHZ);
AF_DCMotor Motor_Right_Rear(2,MOTOR12_1KHZ);
SoftwareSerial btSerial(RX,TX);
void setup() {
Serial.begin(9600);
btSerial.begin(9600);
servo.attach(9);
servo.write(45);
pinMode(Led,OUTPUT);
Motor_Left_Front.setSpeed(255);
Motor_Right_Front.setSpeed(255);
Motor_Left_Rear.setSpeed(255);
Motor_Right_Rear.setSpeed(255);
}
void loop() {
DistanceLoop();
if(btSerial.available())
{
data2=btSerial.read();
Serial.print(data2);
//data=Serial.read();
Serial.print(data2, HEX);
Serial.print(" - ");
Serial.println((char) data2);
switch(data2)
{
case '0'://Reset servo position
servo.write(45);
break;
case '1'://Look right
servo.write(90);
break;
case '2'://Look left
servo.write(-90);
break;
case '3': //ServoMotor and Distance (HC-SR04)
ServoRotation();
break;
case 'O': //Led OFF
btSerial.print("Led OFF");
btSerial.print("");
digitalWrite(Led,LOW);
break;
case 'N': //Led ON
btSerial.print("Led ON");
btSerial.print("");
digitalWrite(Led,HIGH);
break;
case 'F': //Forward
btSerial.print("FORWARD");
btSerial.print("");
Motor_Left_Front.run(FORWARD);
Motor_Right_Front.run(FORWARD);
Motor_Left_Rear.run(FORWARD);
Motor_Right_Rear.run(FORWARD);
break;
case 'B': //Backward
btSerial.print("BACKWARD");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(BACKWARD);
Motor_Right_Rear.run(BACKWARD);
break;
case 'S': //Stop
btSerial.print("STOP");
btSerial.print("");
Motor_Left_Front.run(RELEASE);
Motor_Right_Front.run(RELEASE);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(RELEASE);
break;
case 'R': //Turn Right
btSerial.print("Turn Right");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(BACKWARD );
break;
case 'L': //Turn Left
btSerial.print("Turn Left");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(BACKWARD);
Motor_Right_Rear.run(RELEASE );
break;
}
}
}
void ServoRotation()
{
//senso orario
servo.write(0);
delay(300);
servo.write(45);
Distance();
delay(300);
servo.write(90);
delay(300);
//anti-orario
servo.write(135);
delay(300);
servo.write(90);
delay(300);
servo.write(45);
Distance();
delay(300);
}
void Distance()
{
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
btSerial.print("Distance: ");
btSerial.print(uS/US_ROUNDTRIP_CM); // convert time into distance
btSerial.println("cm");
btSerial.print("");
if(uS/US_ROUNDTRIP_CM<10)
{
Motor_Left_Front.run(RELEASE);
Motor_Right_Front.run(RELEASE);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(RELEASE);
}
}
void DistanceLoop()
{
unsigned long currentMillis=millis();
if(currentMillis-previousMillis>interval)
{
previousMillis=currentMillis;
Distance();
}
}
@Luca forse non ti è chiara una cosa. Qui NON è un forum di una azienda con personale pagato per rispondere.
Posti la domanda e dopo MENO di 2 ore vuoi risposte!!
Siamo tutti utenti come te, che diamo risposte appena possiamo. Molti lavorano, e visto il periodo, alcuni saranno in ferie.
Certo lo so! Non pretendo una risposta immediata ci mancherebbe! Solo che avevo aperto un'altra discussione per non fare casino con questa ma mi è stata chiusa da Gugliemo perchè era contro il regolamento e mi aveva detto che ci sarebbe stata una risposta qui: ma non la vedo... Comunque aspetto con calma, non ho problemi
Sig. Gugliemo premetto che ieri ho studiato tutto il materiale da lei gentilmente passato ma oggi sono andato contro questo problema che mi fa dubitare parecchio... sopratutto non capisco perchè non possa andare.. mancanza di corrente forse?
Domanda, ma sul monitor seriale, "data2" ti viene stampato sempre correttamemte? Ovvero il carattere arriva e lo vedi giusto?
Guglielmo
P.S.: Per favore, prendi il tuo programma con l'IDE e usa dal menu Tools - > Auto Format, almeno te lo aggiusta che ... attualmente è indentato in modo illegibile ...
allora una cosa che noto subito quando collego il robottino al pc è che il servo che fa girare il sensore hc-sr04 fa dei micromovimenti da me non dati..
ho fatto alcune prove e oggi funziona! Senza cambiare nulla...
infatti con il debug ho questi risultati:
7046 - F
8353 - S
6642 - B
8353 - S
7046 - F
784E - N
794F - O
4931 - 1
4830 - 0
5032 - 2
5032 - 2
4830 - 0
8252 - R
764C - L
764C - L
8353 - S
che sono corretti
l'unica cosa che quando do il comando 1 (ovvero il servo gira a destra per vedere la distanza), la distanza è sempre nulla..
a sinistra e al centro non mi da questi problemi
LucaAlba98:
... l'unica cosa che quando do il comando 1 (ovvero il servo gira a destra per vedere la distanza), la distanza è sempre nulla..
a sinistra e al centro non mi da questi problemi
Riguarda attentamente il codice, magari c'è qualche cosa che ti è sfuggito ... dopo di che inserisci delle Serial.print() dove può essere utile e fatti stampare i valori, così controlli in vari punti di avere ciò che ti aspetti ...
#include <NewPing.h>
#include <AFMotor.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#define PingPin A0
NewPing sonar(PingPin, PingPin);
unsigned long previousMillis = 0;
unsigned long interval = 1000;
const int speed = 20; //velocità in %
#define RX 15 //A1
#define TX 16 //A2
#define Led 17 //A3
int data;
int data2;
Servo servo;
AF_DCMotor Motor_Left_Front(4, MOTOR34_1KHZ);
AF_DCMotor Motor_Right_Front(3, MOTOR34_1KHZ);
AF_DCMotor Motor_Left_Rear(1, MOTOR12_1KHZ);
AF_DCMotor Motor_Right_Rear(2, MOTOR12_1KHZ);
SoftwareSerial btSerial(RX, TX);
void setup() {
Serial.begin(9600);
btSerial.begin(9600);
servo.attach(9);
servo.write(45);
pinMode(Led, OUTPUT);
Motor_Left_Front.setSpeed(255);
Motor_Right_Front.setSpeed(255);
Motor_Left_Rear.setSpeed(255);
Motor_Right_Rear.setSpeed(255);
}
void loop() {
DistanceLoop();
if (btSerial.available())
{
data2 = btSerial.read();
Serial.print(data2);
//data=Serial.read();
Serial.print(data2, HEX);
Serial.print(" - ");
Serial.println((char) data2);
switch (data2)
{
case '0'://Reset servo position
servo.write(45);
break;
case '1'://Look right
servo.write(90);
break;
case '2'://Look left
servo.write(-90);
break;
case '3': //ServoMotor and Distance (HC-SR04)
ServoRotation();
break;
case 'O': //Led OFF
btSerial.print("Led OFF");
btSerial.print("");
digitalWrite(Led, LOW);
break;
case 'N': //Led ON
btSerial.print("Led ON");
btSerial.print("");
digitalWrite(Led, HIGH);
break;
case 'F': //Forward
btSerial.print("FORWARD");
btSerial.print("");
Motor_Left_Front.run(FORWARD);
Motor_Right_Front.run(FORWARD);
Motor_Left_Rear.run(FORWARD);
Motor_Right_Rear.run(FORWARD);
break;
case 'B': //Backward
btSerial.print("BACKWARD");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(BACKWARD);
Motor_Right_Rear.run(BACKWARD);
break;
case 'S': //Stop
btSerial.print("STOP");
btSerial.print("");
Motor_Left_Front.run(RELEASE);
Motor_Right_Front.run(RELEASE);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(RELEASE);
break;
case 'R': //Turn Right
btSerial.print("Turn Right");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(BACKWARD );
break;
case 'L': //Turn Left
btSerial.print("Turn Left");
btSerial.print("");
Motor_Left_Front.run(BACKWARD);
Motor_Right_Front.run(BACKWARD);
Motor_Left_Rear.run(BACKWARD);
Motor_Right_Rear.run(RELEASE );
break;
}
}
}
void ServoRotation()
{
//senso orario
servo.write(0);
delay(300);
servo.write(45);
Distance();
delay(300);
servo.write(90);
delay(300);
//anti-orario
servo.write(135);
delay(300);
servo.write(90);
delay(300);
servo.write(45);
Distance();
delay(300);
}
void Distance()
{
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
btSerial.print("Distance: ");
btSerial.print(uS / US_ROUNDTRIP_CM); // convert time into distance
btSerial.println("cm");
btSerial.print("");
if (uS / US_ROUNDTRIP_CM < 10)
{
Motor_Left_Front.run(RELEASE);
Motor_Right_Front.run(RELEASE);
Motor_Left_Rear.run(RELEASE);
Motor_Right_Rear.run(RELEASE);
}
}
void DistanceLoop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval)
{
previousMillis = currentMillis;
Distance();
}
}
Non penso sia li il problema perchè lo faccio muovere allo stesso modo sia a sinistra che al centro...
La cosa che mi spaventa di più però è il servomotore che sembra che si sforzi a fare movimenti non richiesti quando il robottino viene collegato al pc via usb... o meglio quando gli do alimentazione... ci sono modi per risolverlo??