controller BLDC per e-bike

Salve a tutti!
vi presento il mio progetto, un controller per motori brushless a tre connettori, come quelli della bici elettrica. Questo tipo di motori ha al loro interno un sensore magnetico, anche detto sensore hall, che serve per un corretto timing delle tre fasi del motore. ora, considerando che io sono uno studente del 3° anno delle superiori, potrei aver commesso degli errori molto grossolani. Chi può darmi una mano con questo ambizioso(?) progetto? si accettano suggerimenti per nuove funzioni da sviluppare.

//_____PIN_____
#define H1 2 //hall n1
#define H2 3 //hall n2
#define H3 4 //hall n3
#define M1P 5 //pin ramo positivo, connettore 1
#define M2P 6 //pin ramo positivo, connettore 2
#define M3P 7 //pin ramo positivo, connettore 3
#define M1N 8 //pin ramo negativo, connettore 1
#define M2N 9 //pin ramo negativo, connettore 2
#define M3N 10 //pin ramo negativo, connettore 3
#define Portante 11 //pin PWM
#define mag_p 12 //pin sensore magnetico pedelec
#define acc_p A0 //pin analogico acceleratore

//_____VARIABILI_____
int acc=0; //variabile lettura acceleratore
boolean mag=0; //variabile di lettura sensore magnetico
int Hall_1=0; //variabile di lettura stato sensore hall 1
int Hall_2=0; //variabile di lettura stato sensore hall 2
int Hall_3=0; //variabile di lettura stato sensore hall 3
int Hall_tot=0; //totale binario dei sensori hall

//_____SETUP_____
void setup(){
  
  //definizione dei tre pin hall come input:
  pinMode(H1, INPUT);
  pinMode(H2, INPUT);
  pinMode(H3, INPUT);
  
  //definizione degli output
  pinMode(Portante, OUTPUT);
  pinMode(M1P, OUTPUT);
  pinMode(M2P, OUTPUT);
  pinMode(M3P, OUTPUT);
  pinMode(M1N, OUTPUT);
  pinMode(M2N, OUTPUT);
  pinMode(M3N, OUTPUT);
  
}
//_____timing_motore_____
void timing_motore(){
  //lettura stato sensori hall:
  Hall_1=digitalRead(H1);
  Hall_2=digitalRead(H2);
  Hall_3=digitalRead(H3);

  //conversione necessaria per lo switchcase:
  Hall_tot = Hall_1 + ( Hall_2 * 2 ) + ( Hall_3 * 4 );
  
  //switchcase
  switch(Hall_tot) {
    case 9:
      //M1='+'
      //M2='-'
      //M3='0'
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M1P, HIGH);
      digitalWrite(M2N, HIGH);     
    break;
    case 1:
      //M1='+'
      //M2='0'
      //M3='-'
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M1P, HIGH);
      digitalWrite(M3N, HIGH);
    break;
    case 5:
      //M1='0'
      //M2='+'
      //M3='-'
      digitalWrite(M1P, LOW);
      digitalWrite(M1N, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M2P, HIGH);
      digitalWrite(M3N, HIGH);
    break;
    case 4:
      //M1='-'
      //M2='+'
      //M3='0'
      digitalWrite(M1P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M1N, HIGH);
      digitalWrite(M2P, HIGH);
    break;
    case 12:
      //M1='-'
      //M2='0'
      //M3='+'
      digitalWrite(M1P, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M1N, HIGH);
      digitalWrite(M3P, HIGH);
    break;
    case 8:
      //M1='0'
      //M2='-'
      //M3='+'
      digitalWrite(M1P, LOW);
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M2N, HIGH);
      digitalWrite(M3P, HIGH);
    break;
    default:
      //M1='0'
      //M2='0'
      //M3='0'
      digitalWrite(M1P, LOW);
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M3N, LOW);
    break;
  }
}
//_____LOOP_____
void loop(){
acc=analogRead(acc_p);
map(acc, 0, 1023, 0, 255);
analogWrite(portante, acc);
timing_motore();
}

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Devi cambire i pin tutti insieme, con tante digitalwrite hai un ritardo e ti cambiano a scatti

Concettualmente ci siamo, tranne un paio di errori:

acc = map(acc, 0, 1023, 0, 255);

analogWrite(Portante, acc);

Rieccomi, un piccolo off-topic: non esiste una funzione nel forum che permette di ricevere una notifica quando qualcuno risponde ad un tuo post?
Comunque, non so se le competenze le devo scrivere qui o nella presentazione, gioco coppe e le scrivo in entrambe le parti:

Come informatica, frequento il terzo anno di un' I.T.I.S. indirizzo informatica. Di C e C++ comunque ho una competenza maggiore di quella media della classe, avendo studiato, negli anni, per conto mio.
Comunque, ho appena iniziato col mondo arduino, inizio gia a padroneggiare le funzioni, almeno le più elementari. Devo dire che è molto facile scrivere per arduino (sempre se si conosce la sintassi del C\C++)

Come elettronica, sto appena iniziando con l'elettronica di potenza, e l'ATMega non è il primo che programmo (motorola nonmiricordo :slight_smile: ). Non studiando elettronica a scuola, zompetto tra una guida e un'altra, ma me la cavo un po su tutto. Sto appena avvicinandomi al mondo dell'elettronica di potenza.

Il regolamento.....diciamo che l'ho visto, ma non letto integralmente. Chiedo venia, ma ora non ho proprio tempo. :grin: :grin:

comunque, ecco la versione migliorata del codice.
ho implementato una funzione, trovata nel forum arduino, che permette di cambiare la frequenza del PWM. Considerando che non uso delay, dovrebbe funzionare tutto per bene.

//_____PIN_____
#define H1 2 //hall n1
#define H2 3 //hall n2
#define H3 4 //hall n3
#define M1P 5 //pin ramo positivo, connettore 1
#define M2P 6 //pin ramo positivo, connettore 2
#define M3P 7 //pin ramo positivo, connettore 3
#define M1N 8 //pin ramo negativo, connettore 1
#define M2N 9 //pin ramo negativo, connettore 2
#define M3N 10 //pin ramo negativo, connettore 3
#define portante 11 //pin PWM o DAC (3, 9, 10 o 11)
#define acc_p A0 //pin analogico acceleratore

//_____VARIABILI_____
int acc=0; //variabile lettura acceleratore
boolean mag=0; //variabile di lettura sensore magnetico
int Hall_1=0; //variabile di lettura stato sensore hall 1
int Hall_2=0; //variabile di lettura stato sensore hall 2
int Hall_3=0; //variabile di lettura stato sensore hall 3
int Hall_tot=0; //totale binario dei sensori hall

//_____setPwmFrequency_____ preso dal sito ufficiale di 
//arduino italia
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}


//_____SETUP_____
void setup(){
  
  //definizione dei tre pin hall come input:
  pinMode(H1, INPUT);
  pinMode(H2, INPUT);
  pinMode(H3, INPUT);
  
  /*
    definizione degli output (Il digitalWrite si è reso
    necessario, dato che all'accensione i pin digitali
    andavano automaticamente sullo stato HIGH :(
  */
  pinMode(portante, OUTPUT);
  digitalWrite(portante, LOW);
  pinMode(M1P, OUTPUT);
  digitalWrite(M1P, LOW);
  pinMode(M2P, OUTPUT);
  digitalWrite(M2P, LOW);
  pinMode(M3P, OUTPUT);
  digitalWrite(M3P, LOW);
  pinMode(M1N, OUTPUT);
  digitalWrite(M1N, LOW);
  pinMode(M2N, OUTPUT);
  digitalWrite(M2N, LOW);
  pinMode(M3N, OUTPUT);
  digitalWrite(M3N, LOW);
  
  //cambio frequenza PWM a 31250Hz
  setPwmFrequency(portante, 1);
}

//_____timing_motore_____
void timing_motore(){
  //lettura stato sensori hall:
  Hall_1=digitalRead(H1);
  Hall_2=digitalRead(H2);
  Hall_3=digitalRead(H3);

  //conversione necessaria per lo switchcase:
  Hall_tot = Hall_1 + ( Hall_2 * 2 ) + ( Hall_3 * 4 );
  
  //switchcase
  switch(Hall_tot) {
    case 9:
      //M1='+'
      //M2='-'
      //M3='0'
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M1P, HIGH);
      digitalWrite(M2N, HIGH);     
    break;
    case 1:
      //M1='+'
      //M2='0'
      //M3='-'
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M1P, HIGH);
      digitalWrite(M3N, HIGH);
    break;
    case 5:
      //M1='0'
      //M2='+'
      //M3='-'
      digitalWrite(M1P, LOW);
      digitalWrite(M1N, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M2P, HIGH);
      digitalWrite(M3N, HIGH);
    break;
    case 4:
      //M1='-'
      //M2='+'
      //M3='0'
      digitalWrite(M1P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M1N, HIGH);
      digitalWrite(M2P, HIGH);
    break;
    case 12:
      //M1='-'
      //M2='0'
      //M3='+'
      digitalWrite(M1P, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M1N, HIGH);
      digitalWrite(M3P, HIGH);
    break;
    case 8:
      //M1='0'
      //M2='-'
      //M3='+'
      digitalWrite(M1P, LOW);
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M3N, LOW);
      digitalWrite(M2N, HIGH);
      digitalWrite(M3P, HIGH);
    break;
    default:
      //M1='0'
      //M2='0'
      //M3='0'
      digitalWrite(M1P, LOW);
      digitalWrite(M1N, LOW);
      digitalWrite(M2P, LOW);
      digitalWrite(M2N, LOW);
      digitalWrite(M3P, LOW);
      digitalWrite(M3N, LOW);
    break;
  }
}
//_____LOOP_____
void loop(){
acc=analogRead(acc_p);
acc=map(acc, 0, 1023, 0, 255);
analogWrite(portante, acc);
timing_motore();
}

@cyberhs Non sapevo che il map si usasse così, l'ho sempre dato per scontato :frowning:
@flz47655 Come posso cambiarli tutti insieme?
@nid69ita Grazie dei link, li avevo gia, tranne l'ultimo 8)

Chiedo scusa per il doppio post...UPDATE

In attesa che mi arrivi l'hardware per la bici, mi sono messo un po a pensare a quali funzioni implementare. Ho deciso di creare un sistema con 3 ATMega 328P-Pu, ognuno dei quali fa una propria funzione:

#1: Gestisce il corretto timing del motore;
#2: Gestisce la pedalata assistita, l'acceleratore e lo switch tra queste due modalità;
#3: Gestisce l'LCD 16X2, le impostazioni, i bottoni, il limite dei 25Km\h, i sensori termici (batterie, motore, MOSFets) e stacca l'alimentazione in caso di necessità. Inoltre avevo pensato a mettere anche un sensore di carica (?) sulla batteria, che permettesse di capire la carica residua e in caso di voltaggio troppo basso, di staccare l'alimentazione.

Ho anche progettato l'elettronica, tutta a base di transistor, resistenze e lm7805. Adesso sono fuori casa, conto di poter mettere i tre sorgenti e lo schema dell'elettronica per stasera.

@fiz47655 Ho capito che dovrei andare ad agire sui singoli registri.....senti a me, meglio lasciare tutto così come sta

progetto interessante, come sta procedendo?

hai pensato anche a come disegnare il circuito che eroga la corrente al motore?