Skocz do zawartości

Sterowanie mostkiem L298N


kellyq

Pomocna odpowiedź

Dziwny problem bo próbuję wysterować ten mostek i udaje się obracać silnikiem tylko w jedną stronę (ciśnienie-) . Sygnał wysterowania podaję z drugiego sterownika przez nrf24l01 radiowo. Nie wiem o co chodzi z tym, pewnie jakiegoś byka zrobiłem w kodzie ale nie potrafię namierzyć. Nie chce mi działać "ciśnienie +". Kiedy w kodzie wklepię na obydwa piny wyjściowe cisnienie_IN1 i cisnienie_IN2 wysokie stany to przepinajac kabelki silnik kręci jak trzeba

#include "printf.h"
#include <SPI.h>
#include<nRF24L01.h>
#include "RF24.h"

#define flowSensor 2  
#define led 16
#define praca_przelew 15
#define cisnienie_IN1 5
#define cisnienie_IN2 6

#define cisnienie_PWM 3
#define hydraulika1 17
#define hydraulika2 18
#define hydraulika3 19           

                                      
float calibrationFactor = 2.80;  //było 4, działa odwrotnie
volatile int pulseCount; 
int flowRate;
unsigned long oldTime;
   
  RF24 radio(7,8);
  uint8_t address[][6] = {"2Node", "1Node"};
  int dataListen[3];
  int data[4];
    
    void setup(){ 
    pinMode(flowSensor, INPUT);
    pinMode(led, OUTPUT);
    pinMode(praca_przelew, OUTPUT);
    pinMode(cisnienie_IN1, OUTPUT);
    pinMode(cisnienie_IN2, OUTPUT);
    pinMode(cisnienie_PWM, OUTPUT);
    pinMode(hydraulika1, OUTPUT);
    pinMode(hydraulika2, OUTPUT);
    pinMode(hydraulika3, OUTPUT);

    digitalWrite(cisnienie_IN1, LOW);
    digitalWrite(cisnienie_IN2, LOW);
    analogWrite(cisnienie_PWM, 0);
    
    pulseCount        = 0;
    flowRate          = 0;
    oldTime           = 0;
    attachInterrupt(0, pulseCounter, FALLING);
    
    
    radio.begin();
    radio.setPALevel(RF24_PA_LOW);
    radio.setDataRate(RF24_2MBPS);
    radio.setChannel(124);
    radio.openWritingPipe(address[1]); 
    radio.openReadingPipe(1, address[0]);


}
void loop(){

  radio.startListening();
    if ( radio.available() )
    {
      radio.read(&dataListen, sizeof(dataListen) );
     } 
  delay(8);

  
  if(dataListen[0]==1){               //praca/przelew
    digitalWrite(praca_przelew,LOW);
  }else{
    digitalWrite(praca_przelew,HIGH);
  } 
    if(dataListen[1]>0){               //cisnienie+       
    digitalWrite(cisnienie_IN1,HIGH);
    analogWrite(cisnienie_PWM,125);

  }else{
    digitalWrite(cisnienie_IN1,LOW);
    analogWrite(cisnienie_PWM,0);
  }
  if(dataListen[2]>0){               //cisnienie-
    digitalWrite(cisnienie_IN2,HIGH);
    analogWrite(cisnienie_PWM,125);

  }else{
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
  }  
  
   
  if((millis() - oldTime) > 1000)     //zliczanie flowrate co 1 sek.
  { 
    noInterrupts();      
    flowRate = (((1000.0 /(millis()-oldTime))*pulseCount)/calibrationFactor)*100; //w litrach/min*100
    oldTime = millis();
    pulseCount = 0;
    interrupts();
  }
 
//*************************************************
data[0] = flowRate;
data[1] =0;
data[2] =0;
data[3] =0;
radio.stopListening();
radio.write(&data, sizeof(data));
delay(8);
}

void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

 

Link do komentarza
Share on other sites

Dwie jedynki ustawiłem sobie żeby sprawdzić czy może mikrokontroler aby poprawnie wysterowuje, każdy z pinów sprawdzałem osobno, tylko po to te dwie jedynki, bo myślałem że może mikrokontroler coś oszukuje. Tak to steruję podając tylko na jedno z wyjść wysoki stan.

Sprawdzałem serialem czy mikrokontroler dostaje sygnały z drugiego sterownika, no i dostaje. Coś z tym kodem musi być nie halo bo jeśli zrobię nowy szkic i tylko ustawie stany na wyjściach IN 1 i IN 2 to wszystko działa i kręci się w obie strony

Link do komentarza
Share on other sites

Ciężko się połapać w tym programie, bo nie wiem co i kiedy wysyłasz, ale pierwsze co rzuca mi się w oczy to fakt, że w miejscu ustawienia jednego wyjścia na stan wysoki, wypadałoby od razu ustawić drugie na stan niski np.:

if(dataListen[1]>0){               //cisnienie+       
  digitalWrite(cisnienie_IN1, HIGH);
  digitalWrite(cisnienie_IN2, LOW);
  analogWrite(cisnienie_PWM, 125);
  [...]

Pomijając czy to jest przyczyną błędu to na pewno tak będzie łatwiej to analizować, bo teraz niby robisz to przy odbieraniu jakiś innych danych, ale jest to mało intuicyjne. Możliwe, że coś tam się nadpisuje i w efekcie sterownik dostaje jednak błędne informacje. Najlepiej byłoby wyczyścić ten kod sterujący silnikami i uruchomić dla testu chociaż jeden kierunek.

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Zrobiłem mały teścik, wywołałem serialem to co zapisuje się do tablicy dataListen[ ]. Kiedy na drugim sterowniku naciskam zmianę ciśnienia na plus albo na minus to do 2 i 3 pozycji w dataListen[ ] zapisują się jedynki, kiedy puszczam przycisk wskakują zera. I to działa ok, więc komunikacja jest. 

 

Poprawiłem kod tak jak zasugerowałeś czyli zmieniam obydwa wyjścia IN1 i IN2 dla pewności po naciśnięciu przycisku, kiedy nic nie jest wciśnięte ustawiam obydwa wyjścia w niski stan

    if(dataListen[0]==1){               //praca/przelew
    digitalWrite(praca_przelew,LOW);
  }else{
    digitalWrite(praca_przelew,HIGH);
  } 
    if(dataListen[1]==1){               //cisnienie+       
    digitalWrite(cisnienie_IN1,HIGH);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,125);

  }else{
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
  }
  if(dataListen[2]==1){               //cisnienie-
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,HIGH);
    analogWrite(cisnienie_PWM,125);

  }else{
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
  }

Efekt jest taki że działa tylko zmniejszanie ciśnienia, silnik kręci się. Kiedy chcę zwiększyć ciśnienie to niestety oba wyjścia uC (IN1 i IN2) jest brak napięcia, zmierzone multimetrem, ale w tablicy w odpowiednim miejscu jedynka wskakuje.

Natomias kiedy powyższy kod sobie zakomentuję a wstawię taki, to silnik śmiga w obie strony, o co tu chodzi??? Czy te if-y mam źle napisane czy co?

digitalWrite(cisnienie_IN1,HIGH);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,125);
    delay(3000);
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
    delay(500);
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,HIGH);
    analogWrite(cisnienie_PWM,125);
    delay(3000);
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
    delay(500);

 

 

Link do komentarza
Share on other sites

O kurde, konflikt następuje znaczy na wyjście IN 1 wystawia 1, a później w drugim if-ie wystawia 0 i finalnie oba wyjścia są na 0 bo pomiędzy tymi if-ami jest zbyt krótki czas żeby mostek zareagował. W drugim przypadku czyli ciśnienie-  finalnie 1 na końcu wychodzi. Panie kolego szacun bo bym tego chyba nie rozgryzł. Postaram się inaczej te if-y napisać, chyba trzeba będzie w warunku brać pod uwagę  obydwie zmienne dataListen[1] i dataListen[2]

Link do komentarza
Share on other sites

Tak zmieniłem i śmiga, jeszcze raz dzięki. Teraz tylko jeszcze zaimplementować sterowanie oparte o PID i kilka innych rzeczy ale do wiosny może się wyrobię 😜

   if(dataListen[1]==1&&dataListen[2]==0){               //cisnienie+       
    digitalWrite(cisnienie_IN1,HIGH);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,125);
  }
  if(dataListen[1]==0&&dataListen[2]==1){               //cisnienie-
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,HIGH);
    analogWrite(cisnienie_PWM,125);
  }
  if(dataListen[1]==0&&dataListen[2]==0){               //nic nie wciśnięte
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
  }
  

 

Link do komentarza
Share on other sites

Ja bym to uprościł:

if (dataListen[1] == 1) {
    digitalWrite(cisnienie_IN1,HIGH);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,125);
  }
else if (dataListen[2] == 1) {
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,HIGH);
    analogWrite(cisnienie_PWM,125);
  }
else {
    digitalWrite(cisnienie_IN1,LOW);
    digitalWrite(cisnienie_IN2,LOW);
    analogWrite(cisnienie_PWM,0);
  }
  

Przy okazji załatwiając sprawę wciśnęcia dwóch przycisków jednocześnie...

 

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.