05-12-2022 - Arduino Serial Out
Missie:
Met een Arduino Uno gaan we een toestelletje bouwen om via de pin 1 (TX) een ASCII telegram te versturen.
Dat er signaal komt gaan we bewijzen met een oscilloscoop.
Dat het bericht verstuurd wordt gaan we bewijzen met PUTTY.
Later kunnen we dit mechanisme gebruiken als test instrument.
De data sheet vind je hier.
De Serial - Arduino Reference vind je hier.
Het geheel is hier van afgeleid.
We gaan het programma ontwikkelen voor een Arduino Uno.
In de Serial Reference vind je dan dat een Uno maar een UART heeft. Heb je meer seriele poorten nodig, dan moet je bijvoorbeeld een Mega of een Due gebruiken.
Of... de oorspronkelijke seriële poort functionaliteit laten voor dat wat hij is en de software serië bibliotheek gebruiken.
Let op: je kunt dan niet gelijktijdig zenden en ontvangen. Het is een soort van bit banging.
De bibliotheek gebruikt standaard 8 bits, geen pariteit en een stopbit (8N1).
De bibliotheek kent geïnverteerde logica.
SoftwareSerial Library.
Proof of concept.
Download het volgende programma naar de Arduino Uno.
settings.h
//----------------------------------------------------------------------------+
// File : settings.h |
// Autor : Wim Cranen |
// Website : https://www.wccandm.nl |
// Date design : 5 december 2022 |
// Date tested : 6 december 2022 |
// Version : 0.1 - initial release |
// Test result : OK |
//----------------------------------------------------------------------------+
// Revision history : |
// |
//----------------------------------------------------------------------------+
// --- Defines for SerialOut.ino ----------------------------------------------
#define BAUDRATE0 9600 // Baudrate for the terminal program
#define CONFIG SERIAL_8N1 // Configuration for the terminal program
#define BAUDRATE1 9600 // Baud rate for the software serial
#define RXD1 2 // RXD pin for software serial
#define TXD1 3 // TXD pin for software serial
// constants won't change:
const long BLINKINT = 1000; // interval at which to blink (milliseconds)
const long SENDINT = 5000; // interval at which to send (milliseconds)
SerialOut.ino
//----------------------------------------------------------------------------+
// Program : SerialOut.ino |
// Autor : Wim Cranen |
// Website : https://www.wccandm.nl |
// Date design : 5 december 2022 |
// Date tested : 6 december 2022 |
// Version : 0.1 - initial release |
// Test result : OK |
//----------------------------------------------------------------------------+
// Revision history : |
// |
//----------------------------------------------------------------------------+
//--- Include libraries -------------------------------------------------------
#include <SoftwareSerial.h>
//--- Settings in local directory ---------------------------------------------
#include "settings.h" // is in this folder
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long prevBlinkMillis = 0; // will store last time LED was updated
unsigned long prevSendMillis = 0; // will store last time text was send
//--- Set up a new SoftwareSerial object --------------------------------------
SoftwareSerial SoftSerial(RXD1, TXD1);
//--- setup() -----------------------------------------------------------------
void setup(){
pinMode(ledPin, OUTPUT);
Serial.begin(BAUDRATE0, CONFIG);
Serial.println("Setup: +--- Terminal window started.");
// set pin modes for RXD and TXD
pinMode(RXD1, INPUT);
pinMode(TXD1, OUTPUT);
// start SoftSerial port
SoftSerial.begin(BAUDRATE1);
Serial.println("Setup: +--- New software serial started.");
delay(2000);
while (!SoftSerial.available())
{
Serial.println("Setup: +--- Software serial port is not available");
delay(2000);
} // while !SoftSerial.available
Serial.println("Setup: +--- Software serial port ready");
} // void setup()
//--- loop() is main() --------------------------------------------------------
void loop(){
//--- sendint the text ------------------------------------------------------
unsigned long curSendMillis = millis();
// check if send time elapsed
if (curSendMillis - prevSendMillis >= SENDINT)
{
// save the last time you send the text
prevSendMillis = curSendMillis;
// print to the terminal windos
Serial.println("Hello world");
// if the new serial is available, send text out
if (SoftSerial.available() > 0)
{
// print a messages
SoftSerial.println("Hello world");
} // if SoftSerial.available()
else
{ // not available
Serial.println("Software serial port is not available");
} // else SoftSerial.available()
} // if send millis elapsed
//--- blinking the LED -------------------------------------------------------
// This is just to see that the program is running
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long curBlinkMillis = millis();
// check if blink time elapsed
if (curBlinkMillis - prevBlinkMillis >= BLINKINT)
{
// save the last time you blinked the LED
prevBlinkMillis = curBlinkMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
{
ledState = HIGH;
}
else
{
ledState = LOW;
} // ledState
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
} // if blink millis elapsed
} // void loop()
En dat met een oscilloscoop testen of er signaal is. Ja hoor!
Nu kijken met PUTTY of een vergelijkbaar programma wat de output is.
En wat zien we: gibberish!
Maar hoe komt dat nu? Ook als we kijken naar de uitgangen TX en RX, waar de terminal op zit, zien we gibberish.
Na lang nadenken en het lezen van verschillende stukken komt dan de oorzaak hiervan boven water?
De oorzaak ligt in elk geval niet in de baud rate, het aantal bits, de pariteit of het aantal stop-bits.
Het normale RS232 protocol maakt gebruik van spanningen van -12Volt en +12Volt.
Dit terwijl onze arduino een TTL signaal afgeeft. We moeten een andere kabel nemen om deze signalen goed te presenteren.
Een kabel die TTL signalen naar USB omzet. Ik neem deze kabel met de volgende secificaties.
Specificaties:
3.3V en 5V TTL spanningen (3.3V stuur signalen en 5V compatible input signalen)
Converteert TTL logic levels naar computer RS232 levels
Lengte kabel: 100cm
Draadkleur | Functie |
---|---|
Rood | +5 Volt voeding |
Wit | RX (3.3V-5V) |
Groen | TX(3.3V, een 5V apparaat zal hier doorgaans ook compatible mee zijn) |
Geel of Bruin | RTS(3.3V) |
Blauw | CTS (3.3V-5V) |
wart | GND (min) |
En wat komt dan binnen? Tataaaa.
De weg naar succes is soms hobbelig.