Ciao a tutti.
Sto provando ad implementare un codice che piloti le frecce direzionali dal blocchetto a manubrio della moto leggendolo dal CANBUS sull'interfaccia OBD2.
L'utilizzo dei materiali è il seguente:
Arduino UNO;
MCP2515;
2 RELAY MODULE
Come si evince dallo sketch in allegato, nessun problema a leggere i tasti destra, sinistra, centrale e down.
Il problema nasce nel momento in cui devo far azionare i rele dopo la pressione dei tasti.
Su comando 4 Frecce, sinistra, funziona (ma hanno il delay bloccante e premendo il centrale non disattiva nulla, quindi è inutile);
Su comando destro (impostato con millis) blinka il rele solo quando tengo premuto il pulsante destro.
Il codice è il seguente:
#include <mcp_can.h>
#include <SPI.h>
//buffer
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
// button
const byte btndx[] = {0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; //comando freccia destra
const byte btnsx[] = {0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; //comando freccia sinistra
const byte btnce[] = {0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; //comando centro disattiva frecce
const byte btndn[] = {0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00}; //comando 4 frecce
// tempo
unsigned long previousMillis = 0;
unsigned long currentMillis;
const long intervalon = 500;
const long intervaloff = 500;
const long durata = 10000;
//const long intervalbtn = 5000;
//boolean RELDXSTATE = digitalRead(7);
//boolean RELSXSTATE = digitalRead(8);
int RELDX = 7;
int RELSX = 8;
MCP_CAN CAN0(10); // Set CS to pin 10
void setup()
{
Serial.begin(115200);
if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n");
else Serial.print("MCP2515 Init Failed!!\r\n");
pinMode(2, INPUT); // Setting pin 2 for /INT input
pinMode(RELDX, OUTPUT);
pinMode(RELSX, OUTPUT);
digitalWrite(RELDX, HIGH); //imposto lo stato del rele su spento
digitalWrite(RELSX, HIGH); //imposto lo stato del rele su spento
CAN0.setMode(MCP_NORMAL); // Change to normal mode to allow messages to be transmitted
}
// richiamo tasto centro per disattivare gli indicatori
void ce() {
if (digitalRead(RELDX) == LOW) digitalWrite(RELDX, HIGH); //disattivo le frecce di destra
if (digitalRead(RELSX) == LOW) digitalWrite(RELSX, HIGH); //disattivo le frecce di sinistra
}
// richiamo tasto destro
void dx() { //testata funzione millis
Serial.println("DX");
if (digitalRead(RELSX) == LOW) digitalWrite(RELSX, HIGH);
// if (currentMillis - previousMillis > durata) {
if (digitalRead(RELDX) == LOW){
if (currentMillis - previousMillis > intervaloff){
digitalWrite(RELDX, HIGH);
previousMillis = currentMillis;
}
} else {
if (currentMillis - previousMillis > intervalon){
digitalWrite(RELDX, LOW);
previousMillis = currentMillis;
}
}
}
void sx() {
Serial.println("SX");
if (digitalRead(RELDX) == LOW) digitalWrite(RELDX, HIGH);
digitalWrite(RELSX, LOW);
delay(600);
digitalWrite(RELSX, HIGH);
delay(600);
}
void hazard() {
Serial.println("HAZARD");
digitalWrite(RELSX, LOW);
digitalWrite(RELDX, LOW);
delay(600);
digitalWrite(RELSX, HIGH);
digitalWrite(RELDX, HIGH);
delay(600);
}
void loop()
{
currentMillis = millis();
if(!digitalRead(2)) // If pin 2 is low, read receive buffer
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if (len == sizeof btnsx && memcmp(btnsx, rxBuf, len) == 0){ // pulsante sinistra
if (digitalRead(RELDX) == LOW) digitalWrite(RELDX, HIGH);
digitalWrite(RELSX, LOW);
delay(600);
digitalWrite(RELSX, HIGH);
delay(600);
}
if(!digitalRead(2)) // If pin 2 is low, read receive buffer
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if (len == sizeof btndx && memcmp(btndx, rxBuf, len) == 0) // pulsante destra
dx();
if(!digitalRead(2)) // If pin 2 is low, read receive buffer
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if (len == sizeof btnce && memcmp(btnce, rxBuf, len) == 0) // pulsante disattivazione frecce
ce();
if(!digitalRead(2)) // If pin 2 is low, read receive buffer
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)
if (len == sizeof btndn && memcmp(btndn, rxBuf, len) == 0) // pulsante 4 frecce
hazard();
}
La funzione che dovrei implementare è la seguente:
Tasto DX; disattiva lo stato del RELESX, accende RELEDX ad intermittenza di mezzo secondo per un tempo di 15 secondi (simulazione spegnimento automatico frecce)
Tasto SX; come DX al contrario;
Tasto CENTRO; disattiva le frecce, quindi manda in off RELEDX e RELESX;
Tasto DOWN; se premuto per 3 secondi attiva tutti e due i rele ad intermittenza di mezzo secondo fino a quando o si ripreme DOWN per altri 3 secondi oppure premendo il tasto CENTRO.
C'è qualcuno che protrebbe illuminarmi sulla realizzazione di questo progetto?
Ne approfitto anche per chiedere questo. Perché i rele si disattivano quando è impostato lo stato dei pin 7 e 8 su "HIGH"?
Vi ringrazio anticipatamente per l'attenzione