• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Modelarski sterownik silnika DC na Atmega8 według projektu AVT
#31
Właśnie po to są kursy, by nie zadawać takich pytań elementarnych na forum.
Możesz używać operatorów logicznych LUB (or), ORAZ (and), itd, to jest opisane w specyfikacji języka C.
Jeśli masz drabinkę od dołu, albo od góry to nie trzeba, bo eliminacja jest drabinką.
Jak jest tylko jedno IF to if( (jedno porównanie) and (drugie porównanie)) WykonajPolecenie();, nawiasy wewnętrzne są zbędne.
Słówka and i or działają tylko w Arduino, normalnie dla C/C++ są operatory ||, &&,!. Oczywiście te C/C++ też działają w Arduino, przede wszystkim zresztą, po prostu jest gdzie w plikach zdefiniowane słowo and i jak się pojawi to jest podmieniane na && przez edytor zanim zajmie się tym kompilator.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#32
Kursy owszem tyle ze jak dotąd to nauczyłem się migać diodą w każdym razie w tych podręcznikach które mam. na razie mi kompiluje bez błędu fragment sterowania mostkiem. Może można to lepiej zapisać ale cóż uczę się a to wymaga czasu
Jakies sugestie ? bo się zastanawiam jak zrobić płynny start czyli opóźnienie narastania PWM.
Kod:
  //poczatek do produ
                    //podział sygnału +/- 50
       if(nThrottleIn>1550){
           if (pwM1a>=255) pwM1a=255;
        pwM1a = map(nThrottleIn ,1550, 1995, 0,255);
         digitalWrite(in1a , HIGH);
         digitalWrite(in1b , LOW);
         digitalWrite(pwM1b,LOW);
         analogWrite(pwM1a,9);
          }
          //do tyłu
          else if (nThrottleIn<1450){
             if (pwM1b>=255) pwM1b=255;
              pwM1b = map(nThrottleIn ,1005, 1450, 255, 0);
              digitalWrite(in1a , LOW);
              digitalWrite(in1b , HIGH);
               digitalWrite(pwM1a,LOW);
               analogWrite(pwM1b,10);
              
          }
          else if (nThrottleIn <1550, nThrottleIn> 1450 ) {
             digitalWrite(in1a , LOW);
              digitalWrite(in1b , LOW);
               digitalWrite(pwM1a,HIGH);
               analogWrite(pwM1b,HIGH);
           
          }
 
Odpowiedź
#33
Czemu nie dasz pwm typ char? Wtedy if nie potrzebny bo nigdy nie przekroczy 255
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#34
Bo jeszcze do tego nie doszedłem a konkretnie jak ? i co mnie dziwi ze nie deklaruje sie pinów na poczatku
 
Odpowiedź
#35
Bo błędnie zakładasz, że swoje programy można pisać, jak wyczytasz wybraną lekcję z kursu. Kurs trzeba przerobić w całości, czasami kilka razy, za każdym kolejnym przebiegiem połączą się kolejne kropki tworząc coraz wyraźniejszy obraz o co w ogóle chodzi.
map i drabinka ifów jest na 4 lekcji https://forbot.pl/blog/kurs-arduino-pomi...adc-id3819 , nauka millis w ostatniej lekcji drugiego poziomu kursu, warto też przerobić cały kurs kolejny raz bez delay, z millis().
Żeby móc płynnie coś zmieniać trzeba jakoś zarządzać czasem, odmierzać go sobie by ustalić, czy minęło odpowiednio dużo czasu na wykonanie kolejnego kroku w programie. Odczytana wartość nie musi być przekazana bezpośrednio do PWM, znowu logika, jeśli jedna różni się od drugiej, o więcej niż 10, to zwiększ o 10, wywołuj taką funkcję i sprawdzenie co 20ms (czy o jakikolwiek wybrany interwał czasu mający sens w danym przypadku).
Jak funkcja jazda() jest zbyt skomplikowana to można ją podzielić na etapy ze Switch case, gdzie wyróżnisz różne zachowanie programu, przy jeździe samochodzikiem może to być np. zatrzymany, przyspieszanie, jazda, hamowanie, utrata zasięgu pilota, itp.
Bardzo możliwe, że jak skorzystasz z gotowej biblioteki to wszystko będzie robione bez Twojego zaangażowania, np. w bibliotece do silników krokowych użytkownik wpisuje tylko jakie maksymalne przyspieszenie i jaką maksymalną prędkość może być używana i tu się kończy jego inwencja, podaje nową nową pozycję silnika, a biblioteka sobie tam jedzie wybierając kierunek obrotów i prędkości na każdym etapie.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#36
Alez ja się z Toba zgodzę tyle że to dopiero przede mną bo jakiś cel muszę mieć może za ambitny tyle ze części zakupiłem płytki lezą a programu do regulatora brak bo ten co mam zle działa a mayfrendy niestety nie robią dobrych. A biblioteka motor DC jest ale jeszcze jej nie znam, a co do reszty niepotrzebny jest hamulec, odbiorniki pomimo zaniku sygnał wysyłają nadal ramki w zależności od zaprogramowania albo ostania albo failsafe tak ze to tez zbędne, a jak pisałem docelowo ma byc atmega8 wiec nie wiem czy biblioteka będzie działać.a mam takie pytanie odnosbie delay czy będzie działać tylko lokalnie jak umieszczę wewnątrz if ?
 
Odpowiedź
#37
No i program sie wiesza jak sprawdzić dlaczego ? sprawdzam na monitorze portu
 
Odpowiedź
#38
Wklej ostatnią wersję, która się wiesza. W Arduino pozostaje drukować komunikaty na UART i domyślać się skąd był drukowany ostatni. Albo migać ledem z różnych miejsc programu.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#39
OK prosze, chwilę bardzo krotko działa a potem koniec tz. po wgraniu do procesora i uruchomieniu monitora chwile widze jakis wyniki moze sekunde a potem koniec
Kod:
#define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead

#define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car
// piny stanu PB5>13 PB4>12 PWM PB1>9 PB2>10

int pwM1a;
int pwM1b;
int in1a;
int in1b;

volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long ulStartPeriod = 0; // set in the interrupt
volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
// we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
// is clearer for this first example

void setup()
{
  // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH
  // catching these changes will allow us to calculate how long the input pulse is
  attachInterrupt(THROTTLE_SIGNAL_IN,calcInput,CHANGE);
// piny stanu PB5>13 PB4>12 PWM PB1>9 PB2>10

//#define pwM1a 15 //Atmega PB1-15
//#define pwM1b 16 //Atmega PB2-16
//#define in1a 9 //At PB5-13 mostek H
//#define in1b 10 //At PB5 mostek H
            pinMode(pwM1a, OUTPUT);
            pinMode(pwM1b, OUTPUT);
           pinMode(in1a, OUTPUT);
           pinMode(in1b, OUTPUT);

  Serial.begin(115200);
}

void loop()
{
// if a new throttle signal has been measured, lets print the value to serial, if not our code could carry on with some other processing
if(bNewThrottleSignal)
{
   //Serial.println("szer imp:    ");
   Serial.println(nThrottleIn);
   
   
    Serial.println("  wart PWN1");
     Serial.println(      pwM1a); 
   

   // set this back to false when we have finished
   // with nThrottleIn, while true, calcInput will not update
   // nThrottleIn
   bNewThrottleSignal = false;
}

// other processing ...
}

void calcInput()
{
  // if the pin is high, its the start of an interrupt
  if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH)
  {
    // get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its
    // easy to understand and works very well
    ulStartPeriod = micros();
  }
  else
  {
    // if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
    // start time ulStartPeriod from the current time returned by micros()
    if(ulStartPeriod && (bNewThrottleSignal == false))
    {
      nThrottleIn = (int)(micros() - ulStartPeriod);
      ulStartPeriod = 0;

      // tell loop we have a new signal on the throttle channel
      // we will not update nThrottleIn until loop sets
      // bNewThrottleSignal back to false
      bNewThrottleSignal = true;
     
       // piny stanu PB5>13 PB4>12 PWM PB1>9 PB2>10             
                   
                    //poczatek do produ
                    //podział sygnału +/- 50
       if(nThrottleIn>1550){
           if (pwM1a>=255) pwM1a=255;
        pwM1a = map(nThrottleIn ,1550, 1995, 0,255);
         digitalWrite(in1a , HIGH);
         digitalWrite(in1b , LOW);
         digitalWrite(pwM1b,LOW);
         analogWrite(pwM1a,9);
          }
          //do tyłu
          else if (nThrottleIn<1450){
             if (pwM1b>=255) pwM1b=255;
              pwM1b = map(nThrottleIn ,1005, 1450, 255, 0);
              digitalWrite(in1a , LOW);
              digitalWrite(in1b , HIGH);
               digitalWrite(pwM1a,LOW);
               analogWrite(pwM1b,10);
               
          }
          else if (nThrottleIn <1550, nThrottleIn> 1450 ) {
             digitalWrite(in1a , LOW);
              digitalWrite(in1b , LOW);
               digitalWrite(pwM1a,HIGH);
               analogWrite(pwM1b,HIGH);
           
          }
       
         
     

     
     
       
     }
    }
      //delay(1000);
    }
 
Odpowiedź
#40
Jak pomieszałeś <><>, zamiast zrobić drabinkę < < < to są teraz takie wartości odczytane, z którymi program nie wie co robić, 1550 i 1450 nie pasuje do żadnego ifa. Ewentualnie trzeba >= i <=.
Najpierw zastrzegasz że if (pwM1a>=255) pwM1a=255; ale dopiero potem wyliczasz pwM1a = map(nThrottleIn ,1550, 1995, 0,255);
else if (nThrottleIn <1550, nThrottleIn> 1450 ) a to już nie wiem co ma robić, jeśli to ma być lub to II lub or, a nie przecinek.
Funkcja calcInput() wygląda podejrzanie, jest wywoływana w przerwaniu, jeśli sygnał ma dużą częstotliwość, a nadziubdziałeś do niej trochę obliczeń, wywołujesz w przerwaniu inne funkcje, to może przestać gadać, tym bardziej że w loop znowu drukujesz te wartości na pełnej prędkości, print to inne przerwania, nie ważne czy od ostatniego printa minęło 10us czy 100ms, a Twoje oczy i tak nie dadzą rady czytać szybciej niż 10 linii na s, 10Hz.
W przerwaniu nie powinieneś robić nic poza wyznaczeniem tego czasu impulsu, zdefiniować zmienne jako volatile i do nich przekazać wartości, potem w innej funkcji wywołanej z loop ich użyć.
To musiało tak się skończyć, bo nie panujesz nad upływem czasu.
Mignij sobie LED w przerwaniu, zaświecić na początku i zgaś na koniec, zobacz czy po prostu ten led będzie świecić przez ciągłe wywoływanie.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości