Followliner (FL) – starcie 1

  1. Prosty FL – zbudowany na 2 czujnikach TCRT5000 ustawionych blisko siebie tak, by oba leżały nad czarną linią. Położenie czujek – z przodu, przy napędzie (wiem wiem…).
  2. Instalacja modułu w pojeździe.
  3. Pierwszy program – jedź prosto, gdy oba czujniki „widzą” linię.
  4. Modyfikacja – skręcaj (zatrzymując jedno koło) gdy jedna czujka „gubi” linię.
  5. Modyfikacja – silniki STOP, gdy obie czujki zgubiły linię.

Do zrobienia:

  1. (chwilowo) zostaniemy przy 2 czujkach, za to dodamy regulację szybkości kół w zależności od sygnału na czujce (aby nie było szarpania, a ruch był płynny).
  2. gdy pojazd wyjechał poza linię, to ma się cofnąć (może nawet kilka razy, a jeśli po tych kilku razach dalej nie widać linii – to dopiero wówczas STOP).
  3. zmodyfikujemy tor testowy – łagodniejsze łuki (łatwiejsze, ale z czasem zmienimy).

Liczymy obroty (TCRT5000) – sukces!

Liczymy obroty silniczka D65:

Znalezione obrazy dla zapytania d65 zestaw napedowytutaj nasz program:

 

bool stan, poprz;
unsigned long int t1;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  stan=false;
}

int odczyt;
int licz=0;
void loop() {
  poprz=stan;
  odczyt=analogRead(A0);
  if (odczyt<50)
    stan=true;
  else
    stan=false;
//  Serial.print(odczyt);
//  Serial.print("   ");
//  Serial.print(stan?"jasne":"ciemne");
//  Serial.print("   ");
  if (stan!=poprz){
    licz++;
    Serial.print(" KLIK ");
    Serial.print(licz);
    Serial.print(" ");
    if (licz%2==0){
      Serial.print(1000./(millis() - t1)*60);
      Serial.println(" rpm");
      t1= millis();
    }
  }
//  else
//    Serial.println();
}

I działa bardzo fajnie, nawet z tylko jednym znacznikiem! Wyniki są bardzo powtarzalne (przy zasilaniu około 7V – jeden obrót w 230-240ms, czyli 4 obroty w 1 sekundę, a to daje 4*60=240 obrotów na minutę – rpm).

Rozbudowa?

  1. więcej znaczników (już 2 polepszają sprawę, 4 to zdecydowanie OK).
  2. inny algorytm – zliczanie liczny obrotów i aktualizowanie wartości rpm co określony czas, np. 2 sek

Arduino Cinque

Kolejna płytka ze stajnu Arduino – kompatybilna z UNO, za to wyposażona w dużo mocniejszy procesor (już nie jest zbudowana na bazie ATmegi, a Freedom E310).

Nie tylko nowa szybkość procesora (Freedom E310 to 32bitowy mikrokontroler, mogący działać z szybkością 320MHz, a więc 20x szybciej niż aktualnie UNO), ale także:

  • 16kB RAMu na dane
  • Wi-Fi
  • Bluetooth

Pełna specyfikacja płytki : https://www.allaboutcircuits.com/news/arduino-cinque-brings-together-risc-v-and-the-popular-arduino-platform/

Cena? Jeszcze nie jest znana, ale… tanio nie będzie (porównując do klonów UNO) – pierwsza wersja tej płytki o naziwe HiFive1 kosztowała niecałe $60 (a to juest już druga wersja, ulepszona). Mimo wszystko ciekawa alternatywa.

 

Liczymy obroty (TCRT5000)

Liczymy obroty silniczka D65:

Znalezione obrazy dla zapytania d65 zestaw napedowy

który przy zasilaniu 6V powinien mieć 100 rpm (=obrotów na minutę). My wykorzystujemy poznaną czujkę odbiciową TCRT5000:

 

Znalezione obrazy dla zapytania tcrt5000

Pierwsze zgrubne wyniki dały 1 pełen obrót w czasie 250ms, czyli 240 rpm (trochę dużo, ale to dlatego, że zailalem silniczek 8V – „nielegalnie”). Zrzut ekranu:

oraz program (wyjaśnienia i dyskusja później, jak też i omówienie dokładności pomiaru):

int pomiar[3],i=0,maksior;
unsigned long t1,delta;

void setup() {
  Serial.begin(9600);
  t1=millis();    
}
void loop() {
//  Serial.print(millis());
//  Serial.print("   ");
  pomiar[0]=pomiar[1];
  pomiar[1]=pomiar[2];
  pomiar[2]=analogRead(A0);
  //Serial.println(pomiar[2]);  
  if ((pomiar[1]<950)&&(pomiar[1]>300)&&(pomiar[1]>pomiar[0])&&(pomiar[1]>pomiar[2])){
    delta=millis()-t1;
    if(delta>50){
      Serial.print("1 obrot w ");
      Serial.print(delta);
      t1=millis();    
      Serial.print("ms, czyli rpm=");  
      Serial.println(60*1000.0/delta); 
    }
  }  
  //delay(100);
}

 

 

mikrostyki (w tym PULL-UP) oraz czujka odbiciowa TCRT5000

Mikrostyki i czytanie sygnałów

Dziś były bardzo ważne rzeczy o trybie pracy pinów cyfrowych: INPUT. Wszystko sprawdzaliśmy z mikrostykiem. Zrzut tablicy 😉

Do zapamiętania:

  • INPUT -> domyślny tryb pracy pinów cyfrowych
  • OUTPUT -> gdy chcemy sterować napięciem pinów cyfrowych
  • INPUT_PULLUP = digitalWrite(HIGH) w trybie domyslnym, więc to nie to samo co ta sama komenda w trybi OUTPUT

TCRT 5000

Schemat do zapamiętania:

Znalezione obrazy dla zapytania tcrt5000

Znalezione obrazy dla zapytania tcrt5000Znalezione obrazy dla zapytania tcrt5000

oraz nasz schemat podłączenia (po prawej stronie):

Nie ma co tu pisać o „programie” do odczytywania pomiarów – bo potrzebne jest tylko obsługa wejścia analogowego, np. A0.

Do zapamiętania: TCRT5000 pracuje na odległości do 12mm.

pojazd – różne platformy

Zauważyłem, że na allegro (i innych serwisach) sporo jest ciekawych platform z kołami, tutaj umieszczam kilka z nich – z zapytaniem, czy warto je kupować, bo może samodzielnie zrobi się coś podobnego, z możliwością rozbudowy? Sami decydujcie.

  • ~70 zł, 4WD – platforma z pleksi lub na sklejce, nic poza kołami+silniczkami+podwoziem
  • 40 zł ZK-02 z enkoderami — wyprzedaż, warto się pośpieszyć
  • aa
  • aa
  • aa
  • ~220 zł, LIXBOT Racer ROBOT Arduino UNO R3 STARTER KIT 4WD, więcej gadgetów, ale i cena…

Jeśli linki nie działają, to macie nazwy – trzeba ich szukać.

autor: K.G.

 

joyshield + stringi + nRF24

Dziś nowy gadget:

czyli joy-shield. Co to ten „shield”? To rozszerzenie, z różnymi modułami, które nadrukowane są na płytkę PCB i nie wymagają płytki stykowej i masy przewodów. Taką płytkę „wtyka” się w piny Arduino, tworząc „kanapkę”. Ten shield ma „gierkowe” przeznaczenie – choć my go wykorzystamy do sterowania pojazdem, ale są też inne (do internetu przez kabel eRJotkę, przez sieć bezprzewodową, z kartą SD do zapisu danych, z obsługą silników i inne). Warto łapać okazję na allegro lub podobnych, bo ja swój shield kupiłem za 25 zł! A co on ma w sobie?

  • Joystick (dwie osie + przycisk)
  • cztery przyciski z kolorowymi klawiszami
  • dwa dodatkowe przyciski microswich
  • złącze dla modułów transmisji radiowych:
    — nRF24xx
    —  xbee
    — APC200
  • stabilizator napięcie 3.3V (do zasilania układów radiowych)

Oczywiście moduł (=shield) przeznaczony do współpracy z płytkami Arduino UNO, MEGA, LEONARDO itp. Warto zwrócić uwagę na jakość wykonania – mój ma fajne opisy w łatwo dostępnych miejscach.

Obsługa joysticka – shielda

Okazuje się banalnie prosta. Czytamy położenie dwóch osi (x i y) – czyli porty analogowe A0 i A1 (cóż, ten shield je sobie „rezerwuje” i nie mamy ich możliwosci wykorzystywania). Wszystko ładnie opisane na płytce. Podobnie z przyciskami.

void setup() {
Serial.begin(9600);
}
int x,y;
void loop() {
  x=analogRead(A0);
  y=analogRead(A1);
  Serial.print(x);
  Serial.print("  ");
  Serial.print(y);
  if (digitalRead(5)==1)
    Serial.print(" niebieski");
  if (digitalRead(4)==1)
    Serial.print(" bialy");
  if (digitalRead(3)==1)
    Serial.print(" czerwony");
//i tak dalej
  Serial.println();
  delay(100);
}

Zwracam uwagę na „sprytne” granie metodą print oraz println wraz ze spacjami tak, aby wszystko mieściło się w jednej linii i nie było „pozlepiane”.

A odczytywanie przycisków – skoro używam funkcji digitalRead(pin) to dlaczego nie ma wcześniej pinMode(pin, INPUT)? Otóż domyślnie piny ustawione są w trybie INPUT, dlatego właśnie nic nie dopisywałem. Jesto to warte zapamiętania, co powino nie być trudne – w końcu dla wejść analogowych nie ustawialiśmy w tryb INPUT, czyli z wejściami cyfrowymi jest tak samo.

Stringi = napisy

Temat rzeka… trzeba zacząć, czym są tablice w C. Zauwazyłem, że godnym polecenia jest artykuł na oficjalnej stronie Arduino. Ja dołączam „zrzut ekranu” z zajęć.

Jak zmienić nasz poprzedni kod, aby działał na napisach?

void setup() {
   Serial.begin(9600);
}

String napis;
void loop() {
  napis=String(analogRead(A0));
  napis = napis + "  ";
  napis = napis + String(analogRead(A1));
  if (digitalRead(5)==1)
    napis = napis + String(" niebieski");
  if (digitalRead(4)==1)
    napis += String(" bialy");
  if (digitalRead(3)==1)
    napis += String(" czerwony");
  //i tak dalej
  Serial.println(napis);
  delay(100);
}

Oczywiście nic tutaj nie zyskaliśmy, a nawet gorzej – obsługa klasy String w Arduino jest zasobożerna – czyli mocno powiększa nasz kod, ale tym się jeszcze nie przejmujemy. Na uwagę zasługuje łatwe dodawanie (łączenie) ze sobą napisów – realizuje to zwykły operator + (plus)

Joyshield + nRF24L01+

Łączymy poznane dziś rzeczy z poprzednimi zajęciami i nadajemy to, co robimy na naszym kontrolerze. Właśnie dlatego użyliśmy wersji Stringowej kodu do joysticka, bo radyjko nadawało właśnie napisy – a nawet napisy z maksymalną długością 32 znaków (bajtów). Poniżej kod:

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

RF24 radio(9, 10);//CE, CS

uint8_t rxAddr[6] = "grzyb";

void setup(){
  Serial.begin(9600);
  Serial.print("nRF24 INIT=");
  bool ok=radio.begin();
  Serial.println(ok);
  printf_begin;
  radio.printDetails();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
  
  radio.stopListening();
}

String napis;

void loop(){
  napis = String("Heniek "); 
  napis += String(analogRead(A0));
  napis += " ";
  napis += String(analogRead(A1));
  if (digitalRead(5)==1)
    napis += String(" niebieski");
  if (digitalRead(4)==1)
    napis += String(" bialy");
  if (digitalRead(3)==1) 
    napis += String(" czerwony");
  //i tak dalej<br>
  radio.write(napis.c_str(), napis.length());
  Serial.println(napis);
  delay(100);
}

Na uwagę zasługuje linia nr 37, gdzie musiałem użyć nowej metody klasy String o nazwie c_str(), której zadaniem jest stworzenie napisu w stylu języka C (nieobiektowego). Wymuszone jest to przez metodę write() klasy radio. Dodatkowo, długość napisu w klasie String uzyskujemy za pomocą metody length() – a nie sizeof(napis), gdyż to by zwróciło tylko rozmiar obiektu (a nie danych wewnątrz tego obiektu).

Z kolei w linii 26 rozpocząłem nasz napis imieniem (fikcyjnym) uczestnika koła Fi-BOT tak, aby uruchomiony przeze mnie program odbiornika nRF mógł łatwo zidentyfikować kto mi nadaje (Tosiek, Heniek czy Ziuta — także fikcyjne imiona).

Co dalej?

Wydawać by się mogło, że trzeba teraz tak przygotowany kod uruchomić do sterowania pojazdem. Nieprawda. Było by to baaaardzo kłopotliwe. Problem polega na tym, że trzeba odczytać napis w odbiorniku nRF umieszczonym w pojeździe, a potem odczytać aktualne wychylenie osi X i Y joya, i przyciski. Ale to trudne! Nawet przy pomocy funkcji toInt() zamieniającej napis na liczbę całkowitą – bo najpier należało by podzielić nasz napis na części – może przecinkami, jakoś tak:

123,512,czerwony,zielony

Czyli wówczas przecinek (kropka, myślnik – cokolwiek) by nam oddzielał jedną informację od drugiej, co by było do wykorzystania w połączeniu z metodą indexOf() z klasy String. Cała procedura mogła by wyglądać jakoś tak:

  • odczytujemy napis w pojeździe, przesłany przez joyshield (z przecinkami)
  • skupiamy się na pierwszej części napisu, aż do pierwszego przecinka – wiemy, że ma to być pozycja na osi X – funkcja StringSubstring() i/lub wspomniana indexOf()
  • zamieniamy ten krótki podciąg (od zera do 4 znaków) na liczbę całkowitą – metoda toInt() – i mamy już oś X
  • kasujemy/wyrzucamy z napisu pierwszą część do przcinka, przechodzimy do pozycji na osi Y
  • robimy podobnie, a potem
  • jeśli napis nie jest jeszcze pusty (bo ciągle kasowaliśmy informację o osi X i Y), to znaczy, że mamy jakieś przyciski
  • jeśli jest przecinek, to znaczy, że są nawet dwa (lub więcej) wciśniętych przycisków
  • tworzymy pierwszy podciąg aż do pierwszego przecinka, porównujemy czy jest to „zielony”, „czerwony” itd…
  • po odczytaniu przycisku kasujemy z napisu tą informację
  • jeśli napis niepusty, to są kolejne przyciski…

Proszę zwrócić uwagę, jakie to zagmatfane! Dlatego na kolejnych zajęciach będziemy wysyłać z nadajnika nie napisy (Stringi), ale bajty z informacjami. Dwa bajty wystarczą do podania osi X, kolejne dwa do osi Y, a jeszcze jeden – tylko jeden – do podania stanu wszystkich 7 przycisków na naszym shieldzie. Stworzymy własny protokół danych – podobny do tego, jakiego używaliśmy przy omawianiu oscyloskopu. Dlatego zachęcam do ponownego wczytania się w tamten wpis i opis protokołu danych. Właśnie to nas czeka na następnych zajęciach! Ekscytujące, nieprawdaż? 😉

Przypominam o spotkaniu w ten piątek 19-maja o 14:15 w sprawie XV Festiwalu, a kolejne zajęcia we wtorek 23 maja o godz. 16:15. Nie wiem, czy będziemy mieć siły na 22 więc od razu uprzedzam, że w poniedziałek 22 maja, podczas imprezy Festiwalowej, ustalimy termin kolejnego spotkania Fi-BOTa. Zapraszam!

 

10 sposobów na zniszczenie płytki Arduino?

Warto niszczyć? Tak! O ile to czemuś służy 😉 W tym przypadku warto pozanać 10 sposobów na uszkodzenie/całkowite popsucie płytki Arduino a tym samym nautać czyć się niedoprowadzania do takich sytuacji. A jeszcze lepiej – poczytać co powoduje uszkodzenie płytki (teoria, bez drogiej praktyki) by niedoprowadzać do takich sytuacji.

Stronka, którą polecam do czytania sprzedaje swoją wersję Arduino Uno (o nazwie Ruggedino i cenie jedynie $55) uzbrojoną w zabezpieczenia/ulepszenia pozwalającą uniknąć takich sytuacji. Czy ją kupimy? Może niekoniecznie, ale czytając ten artykuł nauczymy się, co się dzieje gdy zewrzemy ze sobą piny 5V i GND. Taka lekcja jest bardzo przydatna – zachęcam do lektury.

autor: K.G.

 

komunikacja I2C oraz SPI — LCD i nRF24

Dziś sporo o sposobach komunikacji innej niż UART – poznajemy  I2C oraz SPI.

Powyżej „zrzut ekranu” naszych zajęć 😉

Komunikacja I2C

Przeniesiona tutaj.

Komunikacja SPI

Przeniesiona tutaj.

Co dalej?

Oczywiście nic nie stoi na przeszkodzie by połączyć oba poznane dziś urządzenia – i zamiast wyświetlania na monitorze PC-ta (przez port szeregowy) wyświetlać na LCD-ku 16×2…. My na nastepnych zajęciach zastąpimy sterowanie naszymi pojazdami z czujki na podczerwień na wspomnianą właśnie komunikację radiową.

Mam nadzieję, że te nowe „zabawki” (klocki) rozbudzą Waszą wyobraźnię 😉

Kolejne zajęcia w dniu 16-maja o godz. 16:15.  Zapraszam!

(c) K.G. 2017

P.S.

Wpis edytowany w listopadzie 2019: komunikacja I2C oraz SPI przeniesiona do dówch oddzielnych części, bo (jak się okazało) – studenci dość często z tego korzystali.