Arduino jako pilot formule

Chcete si zazávodit na autodráze, ale nemáte soupeře? Proč nezkusit Arduino?

Aby Arduino dokázalo řídit rychlost závodního autíčka, musí znát jeho pozici na dráze. Nejjednodušším způsobem snímání pozice jsou hallovy senzory, upevněné na patřičných místech dráhy, které snímají rozptylové pole magnetů, přilepených na kolečka modelu. Při průjezdu auta kolem senzoru se objeví impuls na jednom ze vstupů  D8 .. D12 Arduinu.

Program:

Jakmile se na některém ze vstupů D8 .. D12 objeví impuls generovaný hallovým senzorem, vyvolá se rutina přerušení, identifikuje se snímač který způsobil přerušení, z pole je načtena příslušná hodnota rychlosti a funkcí analogWrite() se nastaví činitel plnění PWM, určující okamžitou rychlost jízdy autíčka.

Signál je zesílen tranzistory Q1 a 2. Celý obvod je připojen ke dráze místo ovladače.

Přesné umístění snímačů závisí na tvaru vaší dráhy a rychlosti, které zadáte do programu zas určí, jak obtížné bude robotického soupeře porazit.

Kód


//D8..D12: PORT B0..B4, PCINT0..4
#define PORTB_MASK  ((1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4)) //Arduino D8..D12
#define PWM_PIN 5

/* Rychlosti */
const uint8_t speeds[] = {
  190,
  255,
  120,
  110,
  190,
};

void setup()
{
  Serial.begin(115200);
  Serial.println("Užívejte si!");
  PORTB |= PORTB_MASK; // Pull-up resistory povoleny
  PCICR |= (1 << PCIE0); // přerušení pro port B a port C povoleno
  PCMSK0 = (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2) | (1 << PCINT3) | (1 << PCINT4); //Pin Change Interrupt D8..D12 
  pinMode(PWM_PIN, OUTPUT); 
  analogWrite(PWM_PIN, 255); 
} 

/* Nastavení rychlostí auta pro jednotlivé senzory */ 
void set_speed(uint8_t sensor) 
{
  char msg[32]; 
  int speed = 255-speeds[sensor-1]; 
  sprintf(msg, "Sensor č.: %d, Rychlost: %d", sensor, speed); 
  Serial.println(msg); 
  analogWrite(5, speed); 
} 

// Tato přerušovací rutina se volá při změně stavu na některém z pinů D8..D12 
ISR(PCINT0_vect) 
{
  uint8_t b = ~PINB & PORTB_MASK; 
  if(b == 0) return; // Určuje číslo senzoru, kolem kterého auto projelo. 
  volatile uint8_t sensor_nr = 0; 
  while(b) 
  {
    b = b >> 1;
    sensor_nr++;
  }
  set_speed(sensor_nr);
}

void loop()
{
// Smyčka Loop zůstává prázdná, veškerá činnost probíhá v přerušovací rutině
}

Přeloženo z https://create.arduino.cc/projecthub/michalin70/automate-slot-cars-with-an-arduino-011221 a redakčně upraveno.