Ciao a tutti, questo fine settimana avendo un po di tempo a mia disposizione mi sono divertito a costruire un piccolo robot rover,
ho montato anche un piccolo display a 16 caratteri con modulo I2C, il display lo gestisco tramite libreria LiquidCrystal_I2C,
ho scritto il primo codice e ho testato il tutto, sembra funzionare tutto abbastanza bene...
Ora vorrei migliorare il codice, in particolare la gestione del display, e la funzione che accendere dei led quando la luce e bassa (Tramite fotoresistenza collegata al PIN A0)
vorrei integrare la funzione millis() per non avere ritardi
Di seguito metto il codice che ho scritto
Scheda 1:
#include <IRremote.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>
#include "pitches.h"
// BLUETOOTH
const int txPin = 2;
const int rxPin = 3;
SoftwareSerial bluetooth(rxPin, txPin);
// SERVO RUOTE
Servo servo_ruota_destra;
Servo servo_ruota_sinistra;
// SERVO SENSORE ULTRASUONI
Servo servo_ultrasuoni;
// LED
int led = 7;
// PIEZO
int piezo = 8;
int startMelody[] = {
NOTE_E4, NOTE_D4, NOTE_E4, 0, NOTE_F4, NOTE_D5, NOTE_C5};
int noteDurations[] = {
8, 8, 8, 10, 4, 8, 4 };
// CONTROLLO IR
#define tasto_1 0x33B8A05F // AVANTI
#define tasto_2 0x33B8609F // INDIETRO
#define tasto_3 0x33B8E01F // SINISTRA
#define tasto_4 0x33B810EF // DESTRA
#define tasto_5 0x33B820DF // FERMO
#define tasto_6 0x33B8906F // AUMENTA VELOCITA'
#define tasto_7 0x33B850AF // DIMINUISCI VELOCITA'
#define tasto_8 0x33B840BF // START FUNZIONE EVITA OSTACOLI
#define tasto_9 0x33B8C03F // STOP FUNZIONE EVITA OSTACOLI
const short RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;
// SENSORE ULTRASUONI HC-SR04
#define trigPin 10
#define echoPin 11
const int distanza_ostacolo = 20;
long duration, distance;
int leftDistance, rightDistance;
// Display LCD
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
// SENSORE DI LUCE
int sensore_luce = A0;
int luce = 0;
// SET PRESCALE PORTE ANALOGICHE
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// VARIABILE PER LA FUNZIONE EVITA OSTACOLI
int funzione_evita_ostacoli = 0;
// VARIABILE PER LA FUNZIONE AUTO-LIGHT
int funzione_auto_light = 0;
// SETUP
void setup() {
pinMode(led, OUTPUT);
pinMode(piezo, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(sensore_luce, INPUT);
servo_ruota_destra.attach(4);
servo_ruota_sinistra.attach(5);
servo_ultrasuoni.attach(6);
servo_ruota_destra.write(90);
servo_ruota_sinistra.write(92);
servo_ultrasuoni.write(90);
lcd.init();
lcd.backlight();
lcd.print("ARDUROVER-MINI");
lcd.setCursor(0, 1);
lcd.print("VERSIONE 1.0");
for (int thisNote = 0; thisNote < 7; thisNote++) {
int noteDuration = 1000/noteDurations[thisNote];
tone(piezo, startMelody[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
noTone(piezo);
}
// Setta prescale a 32
// Riduci la durata della lettura analogica da 128 micros (standard) a 32
sbi(ADCSRA,ADPS2);
cbi(ADCSRA,ADPS1);
sbi(ADCSRA,ADPS0);
// Seriale
Serial.begin(115200);
bluetooth.begin(115200);
Serial.println("Seriali attive...");
// Avvia la ricezione IR
//irrecv.enableIRIn();
}
void loop() {
luce = analogRead(sensore_luce);
/*-----DEBUG-----*/
// SENSORE DI LUCE
/*Serial.print("Sensore luce:");
Serial.println(luce);
lcd.clear();
lcd.print("Sensore luce:");
lcd.setCursor(0, 1);
lcd.print(luce);
delay(50);*/
// SENSORE ULTRASUONI HC-SR04
/*int distance = ping();
distance = (duration/2) / 29.1;
if (distance >= 200 || distance <= 0){
Serial.println("Fuori distanza!");
lcd.clear();
lcd.print("Fuori distanza!");
}
else {
Serial.print("DISTANZA:");
Serial.print(distance);
Serial.println(" cm");
lcd.clear();
lcd.print("Distanza:");
lcd.setCursor(0, 1);
lcd.print(distance);
lcd.print("cm");
delay(50);
}*/
/*-----FINE DEBUG-----*/
// CONTROLLO REMOTO IR
if (irrecv.decode(&results)) {
Serial.println("Codice IR:");
Serial.println(results.value, HEX);
if (results.value == tasto_1) {
avanti();
}
else if (results.value == tasto_2) {
indietro();
}
else if (results.value == tasto_3) {
sinistra();
}
else if (results.value == tasto_4) {
destra();
}
else if (results.value == tasto_5) {
fermo();
}
irrecv.resume();
}
// CONTROLLO SERIALE/BLUETOOTH
byte val;
if (bluetooth.available()) {
val = bluetooth.read();
if (val == 'w'){
avanti();
}
else if (val == 'x'){
indietro();
}
else if (val == 'a'){
destra();
}
else if (val == 'd'){
sinistra();
}
else if (val == 's'){
fermo();
}
else if (val == 'l'){
digitalWrite(led, HIGH);
}
else if (val == 'L'){
digitalWrite(led, LOW);
}
else if (val == 'c'){
tone(piezo, NOTE_C5);
delay(400);
noTone(piezo);
delay(100);
tone(piezo, NOTE_C5);
delay(300);
noTone(piezo);
}
else if (val == 'o'){
funzione_auto_light = 1;
}
else if (val == 'O'){
funzione_auto_light = 0;
}
else if (val == 'e'){
funzione_evita_ostacoli = 1;
lcd.clear();
lcd.print("FUNZIONE");
lcd.setCursor(0, 1);
lcd.print("EVITA OSTACOLI");
}
else if (val == 'E'){
funzione_evita_ostacoli = 0;
fermo();
lcd.clear();
lcd.print("ARDUROVER-MINI");
lcd.setCursor(0, 1);
lcd.print("VERSIONE 1.0");
}
}
// FUNZIONE AUTO-LIGHT
if (funzione_auto_light == 1) {
auto_light();
}
// FUNZIONE EVITA OSTACOLI
if (funzione_evita_ostacoli == 1) {
evita_ostacoli();
}
}
// SENSORE ULTRASUONI HC-SR04
long ping()
{
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
}
Scheda 2:
// FUNZIONI DI MOVIMENTO
void avanti()
{
servo_ruota_destra.write(180);
servo_ruota_sinistra.write(0);
}
void indietro()
{
servo_ruota_destra.write(0);
servo_ruota_sinistra.write(180);
}
void destra()
{
servo_ruota_destra.write(0);
servo_ruota_sinistra.write(0);
}
void sinistra()
{
servo_ruota_destra.write(180);
servo_ruota_sinistra.write(180);
}
void fermo()
{
servo_ruota_destra.write(90);
servo_ruota_sinistra.write(92);
}
// FUNZIONE AUTO-LIGHT
void auto_light()
{
if(luce > 900) {
digitalWrite(led, HIGH);
} else {
digitalWrite(led, LOW);
}
}
// FUNZIONE EVITA OSTACOLI
void evita_ostacoli()
{
int distanza = ping();
if (distanza > distanza_ostacolo) {
avanti();
}
else {
fermo();
servo_ultrasuoni.write(0);
delay(300);
rightDistance = ping();
delay(300);
servo_ultrasuoni.write(180);
delay(300);
leftDistance = ping();
delay(300);
servo_ultrasuoni.write(90);
delay(400);
compareDistance();
}
}
void compareDistance()
{
if (leftDistance>rightDistance)
{
indietro();
delay(300);
destra();
delay(400);
fermo();
delay(100);
}
else if (rightDistance>leftDistance)
{
indietro();
delay(300);
sinistra();
delay(400);
fermo();
delay(100);
}
else {
sinistra();
delay(600);
fermo();
delay(100);
}
}
Se c'è qualcuno che può aiutarmi a migliorarlo accetto tutti i consigli,
avrei anche una domanda riguardo la gestione del display,
in che si fà a cancellare solo una riga sul display senza cancellare tutto?
scrivendo lcd.clear(); si cancella tutto.
Mentre lo scrolling del testo in che modo si fa?
Grazie in anticipo ciao...