Inzicht in de mobiliteit van de toekomst met robotauto's, deel 3
Welkom bij het derde deel van onze blogserie over robotauto's. In het eerste deel leerden we over de basisprincipes van het basisvoertuig. In het tweede deel ontwikkelden we een universeel codesysteem om de rijstappen van de robotauto te definiëren en realiseerden we een eenvoudige afstandsbediening met een infrarood afstandsbediening. Vanwege de fysieke beperkingen van deze afstandsbediening, wil ik in deze aflevering de overdracht van rij-instructies met Bluetooth laten zien, bijvoorbeeld van een smartphone naar de BT-ontvanger HC-05. Bluetooth is een 2,4GHz radiosignaal met een kort bereik. Veilig tot ca. 10 m en storingsvrij in zonlicht.
De Bluetooth module HC-05 is eigenlijk een transceiver=zender+ontvanger. We gebruiken hem echter alleen als ontvanger, voor het verzenden van de rij-instructies gebruiken we een Bluetooth APP op een Android smartphone (vanwege de speciale manier waarop Apple met Bluetooth omgaat, werkt het niet met een iPhone). In principe is het ook mogelijk om een Bluetooth afstandsbediening te bouwen met de HC-05; hiervoor zijn echter een tweede HC-05, een microcontroller en een invoerapparaat (joystickcontroller) nodig.
Van de zes pinnen op de HC-05 module zijn er slechts vier nodig: VCC (5V) en GND voor de voeding van de module en RXD en TXD voor de verbinding met twee pinnen van de microcontroller waarop SoftwareSerial is ingesteld. Je kunt het opschrift LEVEL: 3.3V echter niet negeren om de module niet te beschadigen. Op onze microcontroller met 5V logica hebben we een spanningsdeler nodig van 5V naar 3,3V op zijn minst voor de RXD pin, bijvoorbeeld weerstanden van 1 kOhm en 2,2 kOhm.
Het schakelschema: HC-05 module op de microcontroller
De AT-commando's van de HC-05 module voor Arduino microcontrollers
Links van de connector met het opschrift Key zit een klein knopje dat belangrijk is voor de configuratie. Als dit knopje wordt ingedrukt als de module is ingeschakeld, komen we in de AT-commando-modus (de LED knippert langzaam in een ritme van 2s), waarin we de instellingen uitvoeren met zogenaamde AT-commando's (voor Attention, Achtung). Hiervoor gebruiken we een aangepast voorbeeldprogramma, waarbij de gebruikelijke seriële interface is aangesloten op de Seriële Monitor van de Arduino IDE en de HC-05 via SoftwareSerial.
/*
SoftwareSerial meervoudige seriële test
Ontvangt van de hardware-serieel, stuurt naar software-serieel.
Ontvangt van de software-serieel, stuurt naar de hardware-serieel.
Het circuit:
* RX is digitale pin 10 (aansluiten op TX van ander apparaat)
* TX is digitale pin 11 (aansluiten op RX van ander apparaat) // spanningsdeler!
gemaakt in de nevelen der tijd
gewijzigd 25 mei 2012
door Tom Igoe
gebaseerd op het voorbeeld van Mikal Hart
Deze voorbeeldcode is publiek domein.
*/
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX, TX // mySerial veranderd in BTSerial
char c=' '; // Declaratie van variabele voor verzending
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600); // Baud rate changed to 9600
Serial.println("Serial started!");
// set the data rate for the SoftwareSerial port
BTSerial.begin(38400); // Baud rate for BT 38400
Serial.println("BTSerial started!");
}
void loop() { // steeds opnieuw uitvoeren
als (BTSerial.available()) {
c=BTSerial.read();
Serial.write(c);
}
als (Serial.available()) {
c=Serial.read();
BTSerial.write(c);
Serial.write(c); // re-transmission of input in Serial Monitor
}
}
In de volgende afbeelding worden de essentiële AT-commando's gebruikt. Het externe station, de HC-05, stuurt indien nodig een antwoord en bevestigt met OK.
We zijn vooral geïnteresseerd in de naam en het HEX-adres om de module later op de smartphone te kunnen identificeren. De AT commando's worden ingevoerd in de seriële monitor van de microcontroller. In de volgende afbeelding zie je de seriële monitor van de Arduino IDE.
Als je wilt, kun je het standaard wachtwoord 1234 wijzigen met"AT+PSWD=xxxx", waarbij x staat voor een cijfer van 0 tot 9. Controleer vervolgens met"AT+PSWD?" of de invoer is gelukt.
Nadat de invoer is voltooid, wordt de module even losgekoppeld van de voeding. Na het opnieuw inschakelen zonder op een knop te drukken, staat de HC-05 module in de standaardmodus. De LED knippert snel (ca. 5 keer/s).
Aanpassingen aan de RC auto: ander motorschild
Nu naar de robotauto. Nadat we de vorige keer de Motorcontroller V2 hadden gebruikt, die alleen de twee I2C-connectoren SDA=A4 en SCL=A5 nodig heeft voor de besturingssignalen, wil ik deze keer de oudere Motorcontroller V1 introduceren, die veel digitale pinnen blokkeert, maar vaak voor een spotprijsje te koop is.
Ik heb dit Motorshield ook een beetje aangepast om toegang te krijgen voor sensoren en radio-ontvangers. Aan de digitale pinnenkant is er maar één pin die toegankelijk is met een haakse connector: Pen 2. Dit is goed voor degenen die hier de IR-ontvanger willen aansluiten. Er zijn meer uitbreidingsmogelijkheden aan de andere kant, waar je toegang hebt tot alle analoge ingangen en de voeding met behulp van vrouwelijke connectors (ook wel socket connectors genoemd).
Omdat alle analoge ingangen ook als digitale in- of uitgangen kunnen worden gebruikt, hebben we hier de mogelijkheid om onze radio-ontvangers aan te sluiten. Dit werkt uitstekend met de 433 MHz zendontvanger HC-12 (zie volgende aflevering), maar voor de BT ontvanger HC-05 alleen met beperkingen. Ten eerste kunnen we de RXD-pin niet rechtstreeks aansluiten, daarvoor hebben we de spanningsdeler nodig, en ten tweede leveren de pinnen niet genoeg stroom om de module op deze pinnen van stroom te voorzien.
De volgende afbeelding toont een kleine adapter die we zelf hebben gemaakt, die de HC-05 van 5V en massa voorziet via de juiste pinnen, TXD rechtstreeks aansluit op RX van de SoftwareSeriële interface A1 =D15 en RXD via de spanningsdeler op A2 = D16.
Het aansluitschema: HC-05 module met L293D Motorshield op de Arduino microcontroller
De schakeling kan natuurlijk ook worden gerealiseerd op een mini breadboard met jumper kabels.
Net als de vorige keer wordt de code voor de rij-instructies verhoogd of verlaagd met een druk op de knop; deze keer echter niet met IR-afstandsbediening, maar met de aanraakfunctie in de APP van de smartphone en de Bluetooth-vraag via SoftwareSerial.
De HC-05 Bluetooth-module koppelen met een Android-toepassing (APP)
Voordat de APP verbinding kan maken met de Robot Car, moeten we deze in de instellingen koppelen met de Bluetooth-module. Dit zou vrij eenvoudig moeten zijn, aangezien we eerder de AT-commando's hebben gebruikt om de naam en het HEX-adres van de HC-05 op te vragen.
Als het koppelen is gelukt en een geschikte BT app is geïnstalleerd, kan de app worden gestart en ingesteld. Door op het vergrootglas in de linker afbeelding te tikken, worden geschikte apparaten weergegeven. We tikken op de HC-05 en krijgen de melding "connected". De app die ik gebruik biedt verschillende interfaces voor de bediening (middelste afbeelding). Ik heb besloten om de spelcontroller te gebruiken. Rechtsboven in de middelste afbeelding staan twee pijlen die een kleine cirkel vormen. Tik hier op als de verbinding verbroken is.
De rechterafbeelding toont de knoppen van een spelcontroller. Voordat je ze voor het eerst gebruikt, moet je aan de knoppen de numerieke waarden toewijzen die moeten worden doorgegeven als je erop tikt.
Voor de cursorknoppen heb ik de numerieke waarden 1 tot en met 4 met de klok mee gegeven. Aan de andere knoppen heb ik de numerieke waarde 5 toegekend. Deze waarden worden in de sketch doorgegeven aan de variabele blueToothVal en leiden in de if-pointers van de functie loop() tot de bepaling van de code voor het besturingsniveau.
De veranderingen van Infrarood naar Bluetooth en Motorcontroller V2 naar V1 veroorzaken enkele wijzigingen in het hoofdgedeelte van de schets. Aan de andere kant verandert er bijna niets in de motor() functie. Alleen in de notatie worden de functies motor1->setSpeed() nu motor1.setSpeed() vanwege de verschillende programmabibliotheken (libraries).
De programmacode: Een RC-auto bouwen voor Arduino
* Voorbeeldcode voor robotauto met motorschild V1 en BT-ontvanger HC-05, vanaf 20220515
* gebaseerd op Adafruit Motor shield V2 bibliotheek, copyright Adafruit Industries LLC
* deze code is publiek domein, veel plezier!
* aangepast voor Funduino
* Pinnen
* BT VCC naar Arduino 5Vuit.
* BT GND naar GND
* Arduino A1=15 (SS RX) - BT TX geen spanningsdeler nodig
* Arduino A2=16 (SS TX) - BT RX via een spanningsdeler(5vnaar 3,3v)
*/
#include <AFMotor.h>
AF_DCMotor motor1(2);
AF_DCMotor motor2(3);
#include <SoftwareSerial.h>
// HC-05 initialiseren
SoftwareSerial BTSerial(15, 16); // RX, TX kruisen naar TX, RX(spanningsdeler)
char blueToothVal;
int x = 0;
int y = 0;
int links = 0;
int rechts = 0;
int code = 5555;
int speedL = 0;
float factor = 1.8; // Correctie voor speedLevel 255/100 * 6V/VBatt
void setup() {
Serial.begin(9600); // set up Serial Monitor at 9600 bps
Serial.println("Motor test!");
BTSerial.begin(9600); // set up transmission speed for HC-12
Serial.println("SoftwareSerial initialized!");
} // einde setup
void loop() {
if(BTSerial.available()) //als data is ontvangen ...
Serial.print("beschikbaar");
{
blueToothVal=BTSerial.read();//..sollen diese ausgelesen werden
Serial.println(blueToothVal);
}
if (blueToothVal=='1') //als de Bluetooth-module een "1".... ontvangt
{
if (code<9000) code = code + 1000;
Serial.print("Code = ");
Serial.println(code);
}
anders als (blueToothVal=='2') //als de Bluetooth-module een "2"....ontvangt
{
if ((code-1000*int(code/1000))<900) code = code + 100;
Serial.print("Code = ");
Serial.println(code);
}
else if (blueToothVal=='3') //als de Bluetooth-module een "3"ontvangt ....
{
if (code>2000) code = code - 1000;
Serial.print("Code = ");
Serial.println(code);
}
else if (blueToothVal=='4') //als de Bluetooth-module een "4"ontvangt ....
{
if (code-1000*int(code/1000) > 200) code = code - 100;
Serial.print("Code = ");
Serial.println(code);
}
else if (blueToothVal=='5') //als de Bluetooth-module een "5"ontvangt...
{
code = 5555;
Serial.print("Code = ");
Serial.println(code);
}
delay(200); //kleine vertraging voor betere seriële communicatie en om stuiteren te voorkomen
motor();
} // einde lus
void motor(){
int speedLevel[9]={-100,-80,-60,-40,0,40,60,80,100};
y = int(code / 1000);
x = int((code - 1000*y) / 100);
speedL = speedLevel[y-1];
Serial.print("code = ");
Serial.print(code);
Serial.print(" y =");
Serial.print(y);
Serial.print(" x =");
Serial.print(x);
Serial.print(" speedL =");
Serial.println(speedL);
//Correctie van de snelheidsstappen voor bochten
als (x==1){
right = speedL+20;
left = speedL-20;
}
anders als (x==2){
right = speedL+15;
left = speedL-15;
}
anders als (x==3) {
right = speedL+10;
left = speedL-10;
}
anders als (x==4) {
right = speedL+5;
left = speedL-5;
}
anders als (x==6) {
right = speedL -5;
left = speedL+5;
}
anders als (x==7) {
right = speedL-10;
left = speedL+10;
}
anders als (x==8) {
right = speedL-15;
left = speedL+15;
}
anders als (x==9) {
right = speedL-20;
left = speedL+20;
}
anders {
right = speedL;
left = speedL;
}
//Invoer van de rijstappen voor "links" en "rechts
Serial.print("links = ");
Serial.print(left);
Serial.print(" rechts = ");
Serial.println(rechts);
als (links < 40 & links > -40) {
motor1.run(RELEASE);
}
als (rechts < 40 & rechts > -40) {
motor2.run(RELEASE);
}
als (links>=40) {
if (left>100) left=100;
motor1.run(FORWARD);
motor1.setSpeed(left * factor);
}
als (rechts>=40) {
if (right>100) right=100;
motor2.run(FORWARD);
motor2.setSpeed(right * factor);
}
als (links<= -40) {
if (left<-100) left=-100;
motor1.run(BACKWARD);
left = -left;
motor1.setSpeed(left * factor);
}
als (rechts<= -40) {
if (right<-100) right=-100;
motor2.run(BACKWARD);
right = -right;
motor2.setSpeed(right * factor);
}
} // einde motor
Tot zover de op één na goedkoopste oplossing voor een robotauto met afstandsbediening (ervan uitgaande dat je een Android smartphone hebt). De volgende keer zal ik laten zien hoe eenvoudig het is om een 433 MHz zendontvanger HC-12 te integreren. Hiermee kan zelfs een bereik van enkele honderden meters worden bereikt. De kosten nemen echter toe omdat er nu twee zendontvangers en nog een microcontroller nodig zijn. Tot dan.