• 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
Dźwięk Park Assist z magistrali CAN pojazdu
#1
Witajcie, nie mam pojęcia jak zastąpić funkcję "delay" w tym kodzie , ogólnie program działa ale delay opóźnia działanie , próbowałem z millis ale bez skutku.
Kod:
#include <SPI.h>          //SPI is used to talk to the CAN Controller
#include <mcp_can.h>
#include <defaults.h> // added
#include <global.h>   // added
const int ledPin = 8; //Led is buzzer connected to pin 8 added

MCP_CAN CAN(10);          //set SPI Chip Select to pin 10

unsigned char len = 0;
unsigned char buf[8];
unsigned int canID;


//******************************** Setup *********************************//

void setup()
{
  Serial.begin(115200);   //to communicate with Serial monitor
  pinMode(ledPin, OUTPUT); //Set digital pin 8 to OUTPUT for buzzer
 

//tries to initialize, if failed --> it will loop here for ever
START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS))      //setting CAN baud rate to 500Kbps
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        nosound();
        delay(100);
        goto START_INIT;
    }
}

void sound1() // for distance 1
{
          digitalWrite(ledPin, HIGH); //Set LED on
          delay(500);
          digitalWrite(ledPin, LOW); //Set LED off
}

void sound2() // for distance 2
{
          digitalWrite(ledPin, HIGH); //Set LED on
          delay(300);
          digitalWrite(ledPin, LOW); //Set LED off
}

void sound3() // for distance 3
{
          digitalWrite(ledPin, HIGH); //Set LED on
          delay(100);
          digitalWrite(ledPin, LOW); //Set LED off
}

void sound4() // for distance 4
{
          digitalWrite(ledPin, HIGH); //Set LED on
          delay(50);
          digitalWrite(ledPin, LOW); //Set LED off
}

void nosound() // for stop buzzer
{
                    digitalWrite(ledPin, LOW); //Set LED off
}

void loop()
{
    if(CAN_MSGAVAIL == CAN.checkReceive())        //check if data coming
    {
        CAN.readMsgBuf(&len, buf);    //read data,  len: data length, buf: data buffer
        canID = CAN.getCanId();       //getting the ID of the incoming message
        CAN.init_Mask(0, 0, 0x597);
       
        if (canID == 0x597)            //reading only our beloved 0x597 message
        {
          Serial.print("ID is: ");
          Serial.print(canID, HEX);     //printing the ID in its standard form, HEX

          Serial.print("    Length is: ");
          Serial.println(len);

          Serial.println("\n\n");
         
           
         

          // ** distance signal read
         
          if((buf[0] == 0x40) )
          {
            Serial.println("Byte 0 Sygnał odległości : 1 +");
            sound1();
           
          }

          if((buf[0] == 0x41) )
          {
            Serial.println("Byte 0 Sygnał odległości 2 : ++");
            sound2();
           
          }

          if((buf[0] == 0x42) )
          {
            Serial.println("Byte 0 Sygnał odległości 3 : +++");
            sound3();
          }

         
          if((buf[0] == 0x43) )
          {
            Serial.println("Byte 0 Sygnał odległości 3 : +++");
            sound4();
          }

          else if((buf[0] | 0x40, 0x41, 0x42, 0x43) )
          {
            Serial.println("no data");
            nosound();
          }
         
         }
      }
}
 
Odpowiedź
#2
Mam taki przykład, pikający buzzer (czy tam migający led) włącza się na określony czas przyciskiem, można też tym samym przyciskiem wyłączyć go wcześniej.
Kod:
#include "OneButton.h"


uint32_t czasTeraz,czasPoprzedni,tik=10;
uint8_t nTik,sekundy,minuty,godziny,dni;
bool fnTik,fsekundy,fminuty,fgodziny,fdni;
const uint8_t buzzerPin=5;
uint8_t czasbuzzer;
bool fbuzzer, migaj;

OneButton button1(2, true);

void setup() {
  // put your setup code here, to run once:


pinMode(buzzerPin,OUTPUT);
Serial.begin(115200);



  // link the button 1 functions.
  button1.attachClick(click1);
//  button1.attachDoubleClick(doubleclick1);
//  button1.attachLongPressStart(longPressStart1);
//  button1.attachLongPressStop(longPressStop1);
//  button1.attachDuringLongPress(longPress1);
 

}


void click1()
{

if (!migaj) {
  migaj=1;
  czasbuzzer=25;
}
else  
{
  migaj=0;
  BuzzerOFF();
}
}



void loop() {
  bool buttonState=0;
  // put your main code here, to run repeatedly:
 
  button1.tick();
  czas();
 

 
 
  if (fsekundy)
  {

  }

  if (migaj) BuzzerBlink();



}

void BuzzerBlink()
{

  if (fsekundy and czasbuzzer)
  {
    czasbuzzer--;
  }
  if (czasbuzzer)
{
  if (fnTik and nTik%20==false)
  {
    digitalWrite(buzzerPin, ! digitalRead(buzzerPin));
  }
}
else
{
  BuzzerOFF();
}

}

void BuzzerON()
{
digitalWrite(buzzerPin,true);   
}

void BuzzerOFF()
{
digitalWrite(buzzerPin,false);       





void czas()
{
  czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik)
{
  czasPoprzedni=czasTeraz;
  fnTik=1;
  nTik++;
  if(nTik>=(1000/tik))
  {
    nTik=0;
    sekundy++;
    fsekundy=1;
     if (sekundy>=60)
    {
      sekundy=0;
      minuty++;
      fminuty=1;
      if (minuty>=60)
      {
        minuty=0;
        godziny++;
        fgodziny=1;
        if (godziny>=24)
        {
          godziny=0;
          fdni=1;
          dni++;
   
        }
      }
    }
  }
}
}
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
Ok zaimplementowałem , funkcja wywołana poprawnie ale pakiety lecą co 100 ms z prędkością 500kbp/s co skutkuje tylko pykaniem brzęczyka a nie dźwiękiem co 500ms.

Kod:
#include <SPI.h>          //SPI is used to talk to the CAN Controller
#include <mcp_can.h>
#include <defaults.h> // added
#include <global.h>   // added
const int buzzerPin = 8; //Led is buzzer connected to pin 8 added
int buzzerState = LOW; // ledState used to set the LED
unsigned long previousMillis = 0; // will store last time LED was updated
long OnTime = 100; // milliseconds of on-time
long OffTime = 10; // milliseconds of off-time

MCP_CAN CAN(10);          //set SPI Chip Select to pin 10

unsigned char len = 0;
unsigned char buf[8];
unsigned int canID;


//******************************** Setup *********************************//

void setup()
{
  Serial.begin(115200);   //to communicate with Serial monitor
  pinMode(buzzerPin, OUTPUT); //Set digital pin 8 to OUTPUT for buzzer
 

//tries to initialize, if failed --> it will loop here for ever
START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS))      //setting CAN baud rate to 500Kbps
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        nosound();
        delay(100);
        goto START_INIT;
    }
}

void sound1() // for distance 1
{
// check to see if it's time to change the state of the buzzer
unsigned long currentMillis = millis();

if ((buzzerState == HIGH) && (currentMillis - previousMillis >= OnTime))
{
buzzerState = LOW; // Turn it off
previousMillis = currentMillis; // Remember the time
digitalWrite(buzzerPin, buzzerState); // Update the actual LED
}
else if ((buzzerState == LOW) && (currentMillis - previousMillis >= OffTime))
{
buzzerState = HIGH; // turn it on
previousMillis = currentMillis; // Remember the time
digitalWrite(buzzerPin, buzzerState); // Update the actual buzzer
}
}

void sound2() // for distance 2
{
          digitalWrite(buzzerPin, HIGH); //Set LED on
          delay(300);
          digitalWrite(buzzerPin, LOW); //Set LED off
}

void sound3() // for distance 3
{
          digitalWrite(buzzerPin, HIGH); //Set LED on
          delay(100);
          digitalWrite(buzzerPin, LOW); //Set LED off
}

void sound4() // for distance 4
{
          digitalWrite(buzzerPin, HIGH); //Set LED on
          delay(50);
          digitalWrite(buzzerPin, LOW); //Set LED off
}

void nosound() // for stop buzzer
{
                    digitalWrite(buzzerPin, LOW); //Set LED off
}

void loop()


{
    if(CAN_MSGAVAIL == CAN.checkReceive())        //check if data coming
    {
        CAN.readMsgBuf(&len, buf);    //read data,  len: data length, buf: data buffer
        canID = CAN.getCanId();       //getting the ID of the incoming message
        CAN.init_Mask(0, 0, 0x200);
       
        if (canID == 0x200)            //reading only our beloved 0x597 message
        {
          Serial.print("ID is: ");
          Serial.print(canID, HEX);     //printing the ID in its standard form, HEX

          Serial.print("    Length is: ");
          Serial.println(len);

          Serial.println("\n\n");
         
           
         

          // ** distance signal read byte 0
         
          if((buf[0] == 0x40) )
          {
            Serial.println("Byte 0 Sygnał odległości : 1 +");
            sound1();
           
          }

          if((buf[0] == 0x41) )
          {
            Serial.println("Byte 0 Sygnał odległości 2 : ++");
            sound2();
           
          }

          if((buf[0] == 0x42) )
          {
            Serial.println("Byte 0 Sygnał odległości 3 : +++");
            sound3();
          }

         
          if((buf[0] == 0x43) )
          {
            Serial.println("Byte 0 Sygnał odległości 3 : +++");
            sound4();
          }

          else if((buf[0] | 0x40, 0x41, 0x42, 0x43) )
          {
            Serial.println("no data");
            nosound();
          }
         
         }
      }
}
 
Odpowiedź
#4
No ale nie możesz sobie wstawić funkcji z millis i oczekiwać prawidłowego działania, jeśli w innej części programu wstawisz jakiś delay >>>> tik.
Wszystko co robisz musisz sobie przestawić na takie działanie bez delay.
Np. jeśli komunikujesz się przez modem GSM (czy CAN), wysyłasz komunikat, czekasz na odpowiedź, która może przyjść za 1 do 10s, to nie będziesz zatrzymywał działania programu na 10s, bo w tym czasie nie zadziała czujnik zbliżenia i zdemolujesz dom.
Dzielisz taką pracę na etapy, używasz "maszyny stanów". W loop wywołujesz funkcję obsługaModemu(); i ona się wywołuje co każde okrążenie loop, jak dobrze napiszesz program to tak co 63ns, no wiem, że nie, ale co 20us już powinno być. I nie będziesz w tej funkcji robił co 20us wysłania komunikatu, tylko w niej wstawiasz switch case, etap pierwszy wysłanie komunikatu i przeskoczenie do następnego punktu funkcji, np. odbioru. W sekcji odbioru "czekasz" na literki z UART i zapisujesz je do bufora, co sekundę zwiększasz licznik czasu timeout. No oczywiście nie siedzisz w niej, tylko loop naparza ile umie, a każde wywołanie funkcji obsługaModemu(); kieruje od razu do sekcji odbioru literek i sprawdzania timeout. Jak uzbierasz cały komunikat to przeskakujesz do kolejnej sekcji, gdzie prowadzisz dalszą część dialogu, weryfikujesz komunikat, bo może np. zamiast modem to wysłać odpowiedział jakimś błędem, obsługujesz błąd, albo jeśli to koniec wracasz do pierwszej i zaczynasz od nowa. Jeśli przepełni się licznik timeout, tzn. jeśli jego wartość jest większa od jakiegoś założonego czasu, gdzie powinien się pojawić jakiś komunikat zaczynasz od nowa. Tu też można zliczać liczbę timeoutów, bo może modem został u psa w budzie i nigdy nic nie odpowie, może trzeba zaświecić jakiś czerwony led, albo zapikać buzzerem.
A przynajmniej taką mam koncepcję, bo nigdy nie pisałem takiego skomplikowanego programu Big Grin, więc przykładem się niestety nie podzielę. Ale widziałem gdzieś taki w Internecie do DS18B20, tu komunikat trwa 20ms i ktoś zrobił to maszyną stanu w przerwaniach UART, tak że program nawet nie ma 100us czkawki. Są zresztą przykłady w GOOGLE na hasło "arduino state machin example", nawet bibliotekę widzę, nie trzeba było wymyślać koła.
A do UART jest jeszcze taki przykład SERIAL EVENT, tu na forum też wrzuciłem kilka przykładów gdzie "w tle" są odbierane komunikaty, analizowane, przypisywane na podstawie tej analizy wartości do zmiennych i modyfikowane działanie programu.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości