Concept code which launches two threads, one of which implements a Modbus Tunnel protocol to talk with an ISEM, the other which launches a Modbus RTU protocol to talk to a CPUM (most of the Modbus code has been removed prior to publishing.) A canned AC and DC spectra is provided to display wave forms on start-up however the project normally polls for spectra from the ISEM and then plots is (that functionality has been removed prior to publishing.)

Dependencies:   LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI mbed-os BSP_DISCO_F429ZI

/media/uploads/Damotclese/img_20190530_100915.jpg

Plot of the initial start-up canned AC and DC spectra.

Revision:
0:387684ec9d92
diff -r 000000000000 -r 387684ec9d92 NextGen-Exerciser-Modbus.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NextGen-Exerciser-Modbus.cpp	Thu May 30 05:16:27 2019 +0000
@@ -0,0 +1,189 @@
+
+// ----------------------------------------------------------------------
+// NextGen-Exerciser-Modbus.cpp
+//
+// Fredric L. Rice, May 2019
+//
+// o A digital output for an LED is instantiated
+// o A Serial object is instantiated on Serial-1
+// o A thread's mailbox object is instantiated
+// o A Thread object is instantiated
+// o The serial interface is configured
+// o The module's thread is start()ed
+//
+// The LED is toggled according to timing established by a periodic
+// wait() and according to messages pending in the thread's mailbox
+//
+// The mailbox is checked for any messages that need to go out the
+// serial interface, and if there are any, the message is extracted
+// from the mailbox and gets sent out the serial interface. If there
+// are no messages waiting to go out, a Modbus polling message is
+// sent out the serial interface instead.
+//
+// If there is serial data waiting to be read, the data is collected
+// in to a Modbus frame and it gets handled by examining the content
+// of the inbound frame.
+//
+// ----------------------------------------------------------------------
+
+#include "mbed.h"                       // The mbed operating system
+#include "NextGen-Exerciser-Modbus.h"   // Always include ourself
+#include "NextGen-Exerciser-Defines.h"  // For defined constants and MACROs
+
+// ----------------------------------------------------------------------
+// Allocate local data storage
+//
+// ----------------------------------------------------------------------
+
+    static DigitalOut                  st_digitalOutModbusLED(LED1);
+    static Serial                      st_modbusSerial(PA_9, PA_10);    // TX, RX Serial 1 (This one is working)
+    static Mail<st_pendingMessage, 16> st_modbusMailbox;
+    static Thread                      st_threadModbus;
+    static bool                        b_modbusInitialized = false;
+    static char                        c_flipFlop = 0;
+
+    static unsigned char               uch_modbusPollFrame[] =
+    {
+        0xF7, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xDE
+    } ;
+
+// ----------------------------------------------------------------------
+// ModbusCheckInbound()
+//
+// This function will:
+//      o Check to see if the serial interface is readable
+//      o If there are bytes waiting, the bytes are read and get
+//        assembled in to a full Modbus frame.
+//      o The inbound message is handled by passing it to a function
+//        which examines the content of the inbound message
+//
+// ----------------------------------------------------------------------
+static void ModbusCheckInbound(void)
+{
+    // See if there is inbound serial data
+    if (st_modbusSerial.readable())
+    {
+        
+    }  
+}
+
+// ----------------------------------------------------------------------
+// ModbusCheckOutbound()
+//
+// This function will:
+//      o Get a message from the thread's mailbox, waiting for up to
+//        2 milliseconds for a message
+//      o If a message is pending, the message is extracted and then
+//        gets formatted in to an output Modbus message frame
+//      o The newly-formatted Modbus frame gets transmitted out the
+//        serial interface
+//      o The mailbox message gets released back in to the memory pool
+//      o If there was no output message waiting in the mailbox, a
+//        Modbus polling message is sent out the serial interface
+//
+// ----------------------------------------------------------------------
+static void ModbusCheckOutbound(void)
+{
+    // Is there an outbound message waiting? Wait up to 2 milliseconds for one
+    osEvent st_eventResult = st_modbusMailbox.get(2);
+
+    if (st_eventResult.status == osEventMail)
+    {
+        // Get a pointer to the message
+        st_pendingMessage * pst_outFrame = (st_pendingMessage *)st_eventResult.value.p;
+            
+        // Format and send the MODBUS frame
+        
+        // Finished with the message so release it even if it was not sent
+        st_modbusMailbox.free(pst_outFrame);
+    }
+    else
+    {
+        // Send a poll frame
+        st_modbusSerial.write((uint8_t *)uch_modbusPollFrame, sizeof(uch_modbusPollFrame), NULL);
+    }
+}
+
+// ----------------------------------------------------------------------
+// ModbusThread()
+//
+// This function will:
+//      o Get invoked as a thread under the mbed operating system
+//      o Turn ON the lED associated with this module and protocol
+//      o Enter in to a forever loop which wakes up ten times a second
+//      o Drives the module's LED so that it flashes frim time to time
+//        to indicate that the thread is running
+//      o Check to ensure that the module has been initialized
+//      o If the module is initialized (and it should be) checks to
+//        see if there are inbound serial Modbus messages
+//      o Checks to see if there are any outbound serial Modbus messages
+//
+// ----------------------------------------------------------------------
+static void ModbusThread(void)
+{
+    char ch_halfSecond = 5;
+
+    // Set the MODBUS LED to ON to indicate that the thread has started
+    st_digitalOutModbusLED = 1;
+    
+    // Enter in to a forever loop 
+    while (true)
+    {
+        // Sleep for one tenth of a second
+        wait(0.1);
+        
+        // Count down the half second timer and see if it expired
+        if (0 == --ch_halfSecond)
+        {
+            // It has expired so restart the half second time
+            ch_halfSecond = 5;
+            
+            // See if we turn on or turn off the LED
+            if (0 == c_flipFlop)
+            {
+                c_flipFlop = 1;
+            }
+            else
+            {
+                c_flipFlop = 0;
+            }
+
+            st_digitalOutModbusLED = c_flipFlop;
+        }
+
+        // We check to see if there is inbound or outbound serial traffic 10 times a second
+        if (TRUE == b_modbusInitialized)
+        {        
+            // Check for inbound MODBUS frames
+            ModbusCheckInbound();
+        
+            // See if we need to send outbound MODBUS frames
+            ModbusCheckOutbound();
+        }
+    }
+}
+
+// ----------------------------------------------------------------------
+// ModbusInit()
+//
+// This function will:
+//      o Initialize the module protocol's serial interface
+//      o Flag the fact that things are initialized
+//      o Launch the module's thread
+//
+// ----------------------------------------------------------------------
+void ModbusInit(void)
+{
+    // We configure the CPUM MODBUS serial interface
+    st_modbusSerial.baud(115200);
+    st_modbusSerial.format(8, SerialBase::None, 1);
+
+    // Flag the fact that the module has been initialized
+    b_modbusInitialized = true;
+    
+    // Launch the CPUM Modbus thread
+    st_threadModbus.start(ModbusThread);
+}
+
+// End of file
+