Summary/Abstract: This project displays on the serial port the state of a model train. The project builds on a previous project,Track_Train that used 4 LDR sensors to determine the position of a model train.
Possible Audience: Hobbyists who are interested in using the serial port.
Keywords: Arduino IDE, Finite State Machine, Serial Port, PROGMEM
Required Components: The project is based on a previous project that had 4 sensors and 4 3 aspect signals (Red,Amber,Green). To use that project a micro-controller with 4 inputs and 12 outputs is required. For testing an Arduino UNO with 4 sets of LDRs and 4 sets of Red-Amber-Green signals was used.
Required Libraries: LDR_Sensor_RAG that inherits LDR_Sensor_Class so that library will be required also.
A previous project, Track_Train monitored the 4 sensors to determine the train state. That is waiting (no train present), coming the train was over the top sensor, approaching the train was between the two sensors. Knowing the position (state) of the train the program controlled 4 sets of signals. This project will use the state data to display the location of the train on the Arduino IDE Serial Monitor.
A previous project, Track_Train monitored the 4 sensors to determine the train state. That is waiting (no train present), coming the train was over the top sensor, approaching the train was between the two sensors. Knowing the position (state) of the train the program controlled 4 sets of signals. This project will use the state data to display the location of the train on the Arduino IDE Serial Monitor.
The project will be developed using the Arduino IDE.
In the Arduino IDE either:
1. Create a new project. that is file-->new and save the file as Dsp_Train_State. The IDE will give it the extension *.ino.
2. If the previous project, Track_Train is available reload (file-->open) and save as Dsp_Train_State.
If a new project was created:
1. Make copies of the required libraries. LDR_Sensor_RAG and LDR_Sensor_Class. Follow the procedure given in the page Programs
2. Duplicate the Track_Train program by loading the following code:
The circuit for project Track_Train is shown across. The signals are controlled by the current state the_train that are in turn determined by the sequence of inputs on sensors A0 through A3.
For evaluation on the workbench the following prototyping board was used. (Note the LDRs were physically too close to the GREEN Leds so were permanently low resistance (=no train). The solution was to limit the LED current by replacing the 1K ohm with 10Kohm resistors.
Ultimately the display_message( ) function will be placed in the program loop( ).
For testing a Serial.write('.') is used. A dot is displayed on the Serial Monitor each time the code is executed
However the screen would become saturated with dots so a better solution is to only print a dot each time the state is changed. To do this a variable last_state of type where_is_train is created. This is declared as static which means
1. it preserves its value between each pass of loop( ) and
2. it is not known to functions outside of loop(). Further it is initialiased to an unlikely state vacant2.
In each pass of loop( ) the function train( ) is executed returning with the current state the_train. This one dot is printed each time the state changes.
Note in the setup( ) function the serial port is set to 115200 baud.
The objective is to have a function to display the state on the serial monitor. A possible starting point is shown.
For starters display_message( ) will just display a text message to verify operation. This code can be expanded:
where the directive PROGMEM tells the compiler not to place a copy of the data into dynamic memory but the program will use the copy in Flash/ROM. This is done in the procedure/method response that uses a special function pgm_read_byte() to read a character from memory and place it into data/dynamic memory. This copy is then written to the monitor.
This technique is used to save dynamic memory.In the example given using dynamic memory for the messages would use (9 messages each approximately 18 bytes long) 138 bytes which is nearly 7% of the available dynamic memory. This technique is elaborated upon in the page ROM_Data.
Running the program gives the following results on the Arduino Serial Monitor.
The design worked on the bench as expected. Since it built on a previous project LDR_Signal_RAG the messy part of all the wiring from the sensors and signals for the model train layout was in place.
This is only a fun project and the performance is more than adequate. However in a real embedded system it is important to have an appreciation of the performance and to identify any bottlenecks. In this example we have an appreciation of the code that we wrote - there are no delay loops or while statements waiting for something to occur. The code we wrote is non-blocking.
However the code does use the external Serial library. We know nothing of the serial library. Does it wait until the first character is sent before sending the second? The answer is no. There is a 64 character serial buffer which the Serial Library will load. However after the 64th character the library will need to wait until the first character is transmitted before loading character 65.
In this example none of the messages are anywhere near 64 characters in length but in practice we need to be aware that if we are sending messages over 64 characters in length there may be performance issues.