-
Notifications
You must be signed in to change notification settings - Fork 0
Home
(skip to chapter 8, if you only want to implement)
Hello, I'm from Germany and work professionally as an industrial electronics since many years. My job is to put production machines into operation, optimize and repair them and do the troubleshooting. To do this, one of my parts is to look into the programmings of the controls. And from time to time, I do some changes in the programs. Most of the PLC controls are from the Siemens Simatic line, B&R X20 or simular PLC.
In 2015 I started with the Arduino Starter Kit and the C language as a hobby in my free time. It was a little bit overwhelming. Compared to the PLC controls, programming an Arduino like embedded system in C is pretty less structured. You have the setup(), the loop(), many libraries, examples in the Internet and than: Good luck!
I bought to books: Kernighan & Ritchie - C Programming Language 2 and Steven Prata - C Primer Plus Sixth Edition.
With these books I learned competently something about the C language, but not very much about structuring a program for an embedded system.
In the Internet I stumbled over terms like Automata Theory, Finite State Machine and conceptions from Moore and Mealy.
That was the additionally piece to C that I was looking for.
And right on the Arduino homepage I found the framework plus the modeling tool of Miro Samek that integrates different programming concepts.
I decided to start with the controlling of a LED stripe with a handy as an interesting and advanced project for me.
But as a newbie and a hobbyist it took me a longer time to understand Miro's framework and model to end up this project. Puh!
So please don't mind if I'm sometimes a little bit euphoric about my success. And also don't mind if maybe you as a professional C and/or embedded programmer would come to other solutions. I would really like to learn from your reviews, maybe in the Issues.
Within the Issues I list tasks that should or could still be done to improve the project.
But first I had to learn how to program the WS2812B 5050 RGB stripe with the WS2811 Controller.
I found the libraries from Adafruit and the alternative FastLED which in the Internet is mentioned to be faster. Both libraries come with very nice examples.
But I ended up with the small library of Nick Gammon, because it is lightweight and shows me the "bare metal" way to control the stripe so that I could integrate it in my sketch.
The next step was to get the communication between my handy and the Arduino with the Bluetooth module HC-06 to run. For that purpose I found very helpful information from Martyn Currey.
The third challenge was to find something to program a handy app.
Fortunately I didn't had to learn Java as I suspected, because according to my information from the Internet this is the most common language for apps. Presumably this would have cost me a lot of additional time.
So I was glad to find the MIT App Inventor 2. Martyn Currey did already work with it to connect a bluetooth module and the Arduino.
Additional useful help can be found in MIT App Inventor 2 forum by Taifun or searching for Abraham Getzler.
The App Inventor is completely graphical. And it is also event driven like Miro Samek's framework and that was the second challenge. I was used to sequential program structure and had to get used to the event approach. But with all the good informations in the Internet about using the MIT App Inventor 2 I made progress quite soon.
The app looks like this:
Having all things together I was able to realize a first sketch and an app – but got right away into trouble or let's say, had to enter the next level in embedded programming: Dealing with the hardware.
I simply transmitted the color values that I generated with the sliders in my app and soon the Arduino and the app got stuck because of the permanent data transfer.
Through this thread of Robin2 and that from Nick Gammon I learned something about the function of the USART Serial communication and that there are interrupts involved.
And I also learned that during the control of the LED stripe interrupts are not allowed.
So the need of the interrupt for the USART Serial communication and the strictly interdict of using interrupts while controlling the LED stripe doesn't go together. If the interrupts are off, the Serial communication can lose data and if the interrupts are on, the control of the stripe gets corrupted, because of the strict timing that is necessary.
Furthermore I learned that the Serial communication is asynchronous and I'm supposed to use a kind of a handshake and a frame around my communication data like a start and a stop sign for a tougher communication.
For the app I came out with this solution:
Note that I don't react to every changes of the sliders right away but only when the sliders are let gone. That way only the final changes of the values will be communicated. This relieves the communication and shortened it to what is really necessary and so frees time for the LED control.
Second the Bluetooth address of my HC-06 module is integrated for faster establishment of the Bluetooth connection and has to be changed when using a different one.
Even though I tried to structure my sketch as general supposed like using small functions, using a switch/case structure and avoid blocking functions like delay(), I was not very happy with the overview. I needed a few status variables to take care of the context and was jumping from function to function. And with every change I had to check the cross links and go almost through the whole code. This is the same experience I make in my job.
But as better a program is structured and if the structure is anyhow shown in a graphical manner, the better it is to care for.
For that reason I turned to the long way to learn to use the framework and the modeling tool from Miro Samek (link above).
I liked it right away even though my knowledge doesn't reach into its totally depth by now. The graphical modeling tool gives me a good overview coupled with the ability of still using code in the states, in the transitions or even in the underlying ino sketch.
Furthermore I can use hierarchical states what saves me repetitions.
And last but not least the framework does only react on signals and events depending on the current state. For that reason I don't have to lock them in other states manually like in sequential programs.
IMHO all this together are great benefits.
With the state machine implementation it is easy and clear to split the two functions that should never be active at the same time: the Serial communication and the LED control.
One important trick with state machines, respectively event driven transitions from state to state is to use a time tick if needed to repeat something or to move on in a program. I use the same time tick for the periodically check of an app request, the handshake controlled communication and the progress in the LED programs. If different time ticks are needed (like in my first attempt) they can simply be created in the model.
More information about the implementation are in the documentation of the model.
Here's the UML state machine:
So finally I realized my project with the following cornerstones:
A) I use two exclusive (super-)states: LED control and Serial communication.
Both super states and there sub states has to run completely through before they can be changed into the other super state (so called RTC).
B) To reduce the communication load I only transfer the changed values and so the frame is only 4 char long:
1 char for the selected value, together with 1 char of the selected colour or the selected LED program.
Ahead of these 2 chars comes 1 char as a start sign.
And afterwards comes 1 char as a stop sign.
C) I don't use the USART Serial interrupt itself, because it could fire at any time and so causes problems with the LED control (explained above). Instead I look actively time triggered into the USART Serial receive buffer for a new communication request from the app.
D) The app only sends one char as a request, because this will arrive in the USART receive buffer just by hardware, independent of what the software is doing.
(see the very helpful post #11 in this topic)!
E) An once started communication in the app has to be ended before a new one is allowed, to not mess it up.
As the only exception I guard whether there is a failure in the communication (see G).
F) An expected trouble free handshake is implemented this way (see picture below):
If a color or a LED program is changed in the app (4) and there isn't already a communication going on, it first sends only 1 char 'R' as a request to the Arduino and waits for the answer (5).
The char lands in the USART Serial receive buffer. The sketch looks time triggered (6) into the receive buffer and when it sees the request (7), it sends a transmit char 'T' to the app (8).
When the app sees the transmitted char (10), also time triggered (9) by a Clock Timer, it sends the 4 char data (11) and waits for the acknowledge of the Arduino. Because the sketch knows at this time that it awaits data, it looks time triggered (12) for the start sign (13).
With the start sign '<', the transfered data are processed until the stop sign '>' shows up (14). Then the acknowledge sign 'A' is send (14) and the sketch turns to the LED program (15).
When the app receives time triggered (16) the acknowledge sign it becomes ready for a next transmission (17).
The sketch looks periodically time triggered (1, 18) into the receive buffer and turns back right away to the LED program if there is no new request (2, 19).
G) For the reason that the step chain communication handshake could hang up for any means (morelikely the handy than the Arduino), I guard the communication in the app and the sketch with counters and break it if the counters runs out. The app shows a message, the Arduino could have a LED.
Used hardware:
Samsung Galaxy S5 & S7
HC-06 Bluetooth-Modul
Arduino UNO Rev 3
2m 120 LEDs WS2812B 5050 RGB Stripe with WS2811 Controller
AC adapter YU0510 5VDC 10A
To realize my project the following software and files are needed. (Please refer to the linked sides to see how to install and setup the different tools.)
-
the online app Ide MIT App Inventor 2 and my aia file.
-
the Arduino IDE
-
the The Quantum Leaps' QP™ real-time embedded frameworks and the QM™ modeling tool and my model
-
the LED library from Nick Gammon
Put the files into an own directory: \Your Arduino Sketchbook location\libraries\NeoPixels_SPIYour directory should look like this:
-
To build and upload the model, please follow the instructions in AN_Event-Driven_Arduino_QP-QM.pdf - chapter 2.3.
Again for information, because I'm very thankful to them:
for sketch programming:
Robin2, Nick Gammon and here and here, Martyn Currey and here
for QM programming:
here
for app programming:
MIT App Inventor 2 Forum, Taifun and Abraham Getzler on MIT App Inventor 2 Forum