Arduino – Seriële communicatie met een computer
Het volgende voorbeeld laat zien hoe je via de cpu een seriële string naar de arduino kan sturen zodat je verschillende hardware kan aansturen. Deze code is een “bijeen geraapt” en in elkaar gezet stukje, omdat documentatie op internet niet of nauwelijks te vinden is!, heb je verbeteringen, laat het maar weten!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// Voorbeeld van Seriele verbinding cpu > arduino door S. Ebeltjes (domoticx.nl) // EindeKarakter is (#) 1 byte, deze wordt gecontroleerd in de seriele inputstream, // als deze aanwezig is gaat het programma verder met de ontvangen bytereeks. // Variabelen definieren String TotaleString; String EindeKarakter; void setup() { Serial.begin(9600); // opent de seriele poort, zet data snelheid op 9600 bps. } void loop() { if (Serial.available() > 0) { // if-loop als gegevens ontvangen worden via de seriele poort. char InkomendeKarakter = Serial.read(); // lees de byte in die ontvangen wordt. TotaleString += InkomendeKarakter; // bouw totale string op van alle ingekomen bytes. if (String(InkomendeKarakter) == "#") { // if-loop als deze karakter "#" wordt aangetroffen. TotaleString.replace('#', NULL); // zet het karakter "#" om naar een "return" (verwijderen) Serial.println("Ik heb ontvangen: " + TotaleString); // geef weer wat er al ontvangen is. // HIER DE REST VAN HET PROGRAMMA TotaleString = ""; // maak de total string weer leeg. } } } |
Als je nu via de Arduino software de “serial monitor” opent, en daar wat in tikt met als “einde” van je input “#” geeft de arduino weer wat het ontvangen heeft:
Commandos uitvoeren met gegevens
Ik heb de bovenstaande code uitgebreid zodat je ook een digitale poort kan aansturen, zie het voorbeeld hieronder om het ledje (poort 13) aan en uit te zetten, door commando “hoog#” of “laag#” via de seriële poort te verzenden:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// Voorbeeld van Seriele verbinding cpu > arduino door S. Ebeltjes (domoticx.nl) // EindeKarakter is telkens 1 byte, deze wordt gecontroleerd in de serial // seriele inputstream, als deze aanwezig is gaat het programma verder met // de ontvangen bytereeks // Variabelen definieren String TotaleString; String EindeKarakter; int ledPin = 13; void setup() { Serial.begin(9600); // opent de seriele poort, zet data snelheid op 9600 bps. pinMode(ledPin, OUTPUT); } void loop() { if (Serial.available() >0) { // if-loop als gegevens ontvangen worden vie deriele poort. char InkomendeKarakter = Serial.read(); // lees de byte in die ontvangen wordt. TotaleString += InkomendeKarakter; // bouw totale string op van alle ingekomen bytes. EindeKarakter += InkomendeKarakter; // geef inkomende byte een string zodat deze gecontroleerd kan worden. if (EindeKarakter == "#") { // if-loop als deze karakter "#" wordt aangetroffen. TotaleString.replace('#', '\r'); // zet het karakter "#" om naar een "return" (verwijderen) Serial.println("Ik heb ontvangen: " + TotaleString); // geef weer wat er al ontvangen is. // HIER DE REST VAN HET PROGRAMMA if (TotaleString == "hoog\r") { // vergeet de /r niet, deze zit WEL aan de eind van de string. digitalWrite(ledPin, HIGH); // Zet het ledje op poort 13 aan. Serial.println("de led is AAN"); } if (TotaleString == "laag\r") { // vergeet de /r niet, deze zit WEL aan de eind van de string. digitalWrite(ledPin, LOW); // Zet het ledje op poort 13 uit Serial.println("de led is UIT"); } TotaleString = ""; // maak de total string weer leeg. } else { EindeKarakter = ""; // Zet de check van het "einde" karakter weer op nul } } } |
Als je nu via de Arduino software de “serial monitor” opent, kun je daar nu met “hoog#” en “laag#” digitale poort 13 aansturen:
Seriële communicatie met Autoit3
Wat heb je nodig?
1) Autoit3
2) Autoit3 CommMG UDF
Het volgende voorbeeld laat zien hoe je via Autoit3 (basic programmeertaal) deze gegevens die via de seriele poort verzonden worden kan laten weergeven.
Ik heb het voorbeeld op dit forum gebruikt (orginele bestand dd. 2012-09-27) en het gestript / aangepast zodat het in één oogopslag duidelijk wordt hoe het werkt.
De variabelen heb ik bovenin de code gezet, deze moeten uiteraard wel goed ingesteld staan, let erop dat de BAUD rate wel overeenkomt met dat van de Arduino, anders krijg je onjuiste gegevens binnen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
include <GUIConstants.au3> #include <GuiEdit.au3> #include <GuiComboBox.au3> #include <windowsconstants.au3> #include <Buttonconstants.au3> #include 'commMG.au3' ; ComPoort variablen instellen $Ser_Poort = 3 $Ser_SetError = "" $Ser_BaudRate = 9600 $Ser_DataBits = 8 $Ser_Parity = "none" $Ser_Stopbits = 1 $Ser_Flow = 2 ; Compoort intialiseren _CommSetPort($Ser_Poort, $Ser_SetError, $Ser_BaudRate, $Ser_DataBits, $Ser_Parity, $Ser_Stopbits, $Ser_Flow) ; Dit is de GUI #Region ### START Koda GUI section ### Form= Global $Form2 = GUICreate("Autoit3 COMMG Seriele verbinding voorbeeld", 467, 253, 339, 333) Global $Edit1 = GUICtrlCreateEdit("", 10, 25, 449, 223, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY)) GUICtrlSetData(-1, "") Global $Label21 = GUICtrlCreateLabel("Ontvangen via seriele poort:", 10, 6, 142, 17) GUISetState(@SW_SHOW) ;GUI weergeven #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ; Compoort en GUI afsluiten _Commcloseport() Exit EndSwitch ; Haalt karakters op en stuurt deze door als aan deze condities voldaan wordt: ; Onvangen @CR, 20 karakters ontvangen, of er zijn 200ms verstreken. $SerieleData = _CommGetString() If $SerieleData <> '' Then GUICtrlSetData($Edit1, $SerieleData, 1) WEnd ; Compoort afsluiten _Commcloseport() Exit |
Hieronder zie je wanneer alles goed is gegaan de tekst in de “edit box” verschijnen:
Seriële communicatie met Autoit3 (GUI)
Met deze autoit code heb ik 2 knoppen op de gui geplaatst die “hoog#” en “laag#” versturen via de seriële verbinding, de arduino schakelt dan poort 13 (led) aan of uit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <GUIConstants.au3> #include <GuiEdit.au3> #include <GuiComboBox.au3> #include <windowsconstants.au3> #include <Buttonconstants.au3> #include 'commg.au3' ; ComPoort variablen instellen $Ser_Poort = 3 $Ser_SetError = "" $Ser_BaudRate = 9600 $Ser_DataBits = 8 $Ser_Parity = "none" $Ser_Stopbits = 1 $Ser_Flow = 2 ; Compoort intialiseren _CommSetPort($Ser_Poort, $Ser_SetError, $Ser_BaudRate, $Ser_DataBits, $Ser_Parity, $Ser_Stopbits, $Ser_Flow) ; Dit is de GUI #Region ### START Koda GUI section ### Form=M:\! Arduino Serial\commg_voorbeeld.kxf Global $Form2 = GUICreate("Autoit3 COMMG Seriele verbinding voorbeeld", 467, 296, 322, 254) Global $Edit1 = GUICtrlCreateEdit("", 10, 25, 449, 223, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY)) GUICtrlSetData(-1, "") Global $Label21 = GUICtrlCreateLabel("Ontvangen via seriele poort:", 10, 6, 142, 17) Global $KnopAan = GUICtrlCreateButton("AAN", 8, 256, 75, 25) Global $KnopUit = GUICtrlCreateButton("UIT", 88, 256, 75, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ; Compoort & GUI afsluiten _Commcloseport() Exit Case $KnopAan _CommSendstring("hoog#") Case $KnopUit _CommSendstring("laag#") EndSwitch ; Haalt karakters op en stuurt deze door als aan deze condities voldaan wordt: ; Onvangen @CR, 20 karakters ontvangen, of er zijn 200ms verstreken. $SerieleData = _CommGetString() If $SerieleData <> '' Then GUICtrlSetData($Edit1, $SerieleData, 1) WEnd ; Compoort afsluiten _Commcloseport() Exit |
Seriële communicatie met Processing
Het volgende voorbeeld laat zien hoe je via Processing (ook een C++ programmertaal) deze gegevens die via de seriele poort verzonden worden kan laten weergeven, vergeet niet in onderstaande code je eigen COMpoort instellingen te configureren (denk ook aan de baud rate)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import processing.serial.*;// Importeer de seriele bibliotheek (functies die nodig zijn) String inkomendegegevens; // Definieer variabele int lf = 10; // ASCII linefeed // Seriele instellingen #1 Serial serielepoort; // De variabele van de seriele poort String compoort = "COM3"; // Stel hier de COM poort in waar de Arduino op aangesloten is. int baudrate = 9600; // Stel hier de Baudrate in voor de COM poort. (snelheid van dataoverdracht) void setup() { // Seriele instellingen #2 serielepoort = new Serial(this, compoort, baudrate); // Open de seriele poort serielepoort.buffer(10000); // Deze is toch echt nodig anders loopt e.e.a. niet sychroom serielepoort.bufferUntil(lf); // Doorgaan met ontvangen totdat we een nieuwe regel hebben. } void draw() { // Nodig = Loop } void serialEvent(Serial p) { // Deze subroutine wordt aangesproken zodra er iets ontvangen wordt via de seriele poort. inkomendegegevens = serielepoort.readString(); // Inlezen van de ontvangen gegevens print(">Ontvangen gegevens via seriele poort: " + inkomendegegevens); } |