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.

Committer:
Damotclese
Date:
Fri May 31 22:43:55 2019 +0000
Revision:
2:346119b3db6c
Parent:
0:387684ec9d92
Final concept code update, no further updates are expected;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Damotclese 0:387684ec9d92 1
Damotclese 0:387684ec9d92 2 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 3 // NextGen-Exerciser-Modbus.cpp
Damotclese 0:387684ec9d92 4 //
Damotclese 0:387684ec9d92 5 // Fredric L. Rice, May 2019
Damotclese 0:387684ec9d92 6 //
Damotclese 0:387684ec9d92 7 // o A digital output for an LED is instantiated
Damotclese 0:387684ec9d92 8 // o A Serial object is instantiated on Serial-1
Damotclese 0:387684ec9d92 9 // o A thread's mailbox object is instantiated
Damotclese 0:387684ec9d92 10 // o A Thread object is instantiated
Damotclese 0:387684ec9d92 11 // o The serial interface is configured
Damotclese 0:387684ec9d92 12 // o The module's thread is start()ed
Damotclese 0:387684ec9d92 13 //
Damotclese 0:387684ec9d92 14 // The LED is toggled according to timing established by a periodic
Damotclese 0:387684ec9d92 15 // wait() and according to messages pending in the thread's mailbox
Damotclese 0:387684ec9d92 16 //
Damotclese 0:387684ec9d92 17 // The mailbox is checked for any messages that need to go out the
Damotclese 0:387684ec9d92 18 // serial interface, and if there are any, the message is extracted
Damotclese 0:387684ec9d92 19 // from the mailbox and gets sent out the serial interface. If there
Damotclese 0:387684ec9d92 20 // are no messages waiting to go out, a Modbus polling message is
Damotclese 0:387684ec9d92 21 // sent out the serial interface instead.
Damotclese 0:387684ec9d92 22 //
Damotclese 0:387684ec9d92 23 // If there is serial data waiting to be read, the data is collected
Damotclese 0:387684ec9d92 24 // in to a Modbus frame and it gets handled by examining the content
Damotclese 0:387684ec9d92 25 // of the inbound frame.
Damotclese 0:387684ec9d92 26 //
Damotclese 0:387684ec9d92 27 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 28
Damotclese 0:387684ec9d92 29 #include "mbed.h" // The mbed operating system
Damotclese 0:387684ec9d92 30 #include "NextGen-Exerciser-Modbus.h" // Always include ourself
Damotclese 0:387684ec9d92 31 #include "NextGen-Exerciser-Defines.h" // For defined constants and MACROs
Damotclese 0:387684ec9d92 32
Damotclese 0:387684ec9d92 33 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 34 // Allocate local data storage
Damotclese 0:387684ec9d92 35 //
Damotclese 0:387684ec9d92 36 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 37
Damotclese 0:387684ec9d92 38 static DigitalOut st_digitalOutModbusLED(LED1);
Damotclese 0:387684ec9d92 39 static Serial st_modbusSerial(PA_9, PA_10); // TX, RX Serial 1 (This one is working)
Damotclese 0:387684ec9d92 40 static Mail<st_pendingMessage, 16> st_modbusMailbox;
Damotclese 0:387684ec9d92 41 static Thread st_threadModbus;
Damotclese 0:387684ec9d92 42 static bool b_modbusInitialized = false;
Damotclese 0:387684ec9d92 43 static char c_flipFlop = 0;
Damotclese 0:387684ec9d92 44
Damotclese 0:387684ec9d92 45 static unsigned char uch_modbusPollFrame[] =
Damotclese 0:387684ec9d92 46 {
Damotclese 0:387684ec9d92 47 0xF7, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xDE
Damotclese 0:387684ec9d92 48 } ;
Damotclese 0:387684ec9d92 49
Damotclese 0:387684ec9d92 50 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 51 // ModbusCheckInbound()
Damotclese 0:387684ec9d92 52 //
Damotclese 0:387684ec9d92 53 // This function will:
Damotclese 0:387684ec9d92 54 // o Check to see if the serial interface is readable
Damotclese 0:387684ec9d92 55 // o If there are bytes waiting, the bytes are read and get
Damotclese 0:387684ec9d92 56 // assembled in to a full Modbus frame.
Damotclese 0:387684ec9d92 57 // o The inbound message is handled by passing it to a function
Damotclese 0:387684ec9d92 58 // which examines the content of the inbound message
Damotclese 0:387684ec9d92 59 //
Damotclese 0:387684ec9d92 60 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 61 static void ModbusCheckInbound(void)
Damotclese 0:387684ec9d92 62 {
Damotclese 0:387684ec9d92 63 // See if there is inbound serial data
Damotclese 0:387684ec9d92 64 if (st_modbusSerial.readable())
Damotclese 0:387684ec9d92 65 {
Damotclese 0:387684ec9d92 66
Damotclese 0:387684ec9d92 67 }
Damotclese 0:387684ec9d92 68 }
Damotclese 0:387684ec9d92 69
Damotclese 0:387684ec9d92 70 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 71 // ModbusCheckOutbound()
Damotclese 0:387684ec9d92 72 //
Damotclese 0:387684ec9d92 73 // This function will:
Damotclese 0:387684ec9d92 74 // o Get a message from the thread's mailbox, waiting for up to
Damotclese 0:387684ec9d92 75 // 2 milliseconds for a message
Damotclese 0:387684ec9d92 76 // o If a message is pending, the message is extracted and then
Damotclese 0:387684ec9d92 77 // gets formatted in to an output Modbus message frame
Damotclese 0:387684ec9d92 78 // o The newly-formatted Modbus frame gets transmitted out the
Damotclese 0:387684ec9d92 79 // serial interface
Damotclese 0:387684ec9d92 80 // o The mailbox message gets released back in to the memory pool
Damotclese 0:387684ec9d92 81 // o If there was no output message waiting in the mailbox, a
Damotclese 0:387684ec9d92 82 // Modbus polling message is sent out the serial interface
Damotclese 0:387684ec9d92 83 //
Damotclese 0:387684ec9d92 84 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 85 static void ModbusCheckOutbound(void)
Damotclese 0:387684ec9d92 86 {
Damotclese 0:387684ec9d92 87 // Is there an outbound message waiting? Wait up to 2 milliseconds for one
Damotclese 0:387684ec9d92 88 osEvent st_eventResult = st_modbusMailbox.get(2);
Damotclese 0:387684ec9d92 89
Damotclese 0:387684ec9d92 90 if (st_eventResult.status == osEventMail)
Damotclese 0:387684ec9d92 91 {
Damotclese 0:387684ec9d92 92 // Get a pointer to the message
Damotclese 0:387684ec9d92 93 st_pendingMessage * pst_outFrame = (st_pendingMessage *)st_eventResult.value.p;
Damotclese 0:387684ec9d92 94
Damotclese 0:387684ec9d92 95 // Format and send the MODBUS frame
Damotclese 0:387684ec9d92 96
Damotclese 0:387684ec9d92 97 // Finished with the message so release it even if it was not sent
Damotclese 0:387684ec9d92 98 st_modbusMailbox.free(pst_outFrame);
Damotclese 0:387684ec9d92 99 }
Damotclese 0:387684ec9d92 100 else
Damotclese 0:387684ec9d92 101 {
Damotclese 0:387684ec9d92 102 // Send a poll frame
Damotclese 0:387684ec9d92 103 st_modbusSerial.write((uint8_t *)uch_modbusPollFrame, sizeof(uch_modbusPollFrame), NULL);
Damotclese 0:387684ec9d92 104 }
Damotclese 0:387684ec9d92 105 }
Damotclese 0:387684ec9d92 106
Damotclese 0:387684ec9d92 107 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 108 // ModbusThread()
Damotclese 0:387684ec9d92 109 //
Damotclese 0:387684ec9d92 110 // This function will:
Damotclese 0:387684ec9d92 111 // o Get invoked as a thread under the mbed operating system
Damotclese 0:387684ec9d92 112 // o Turn ON the lED associated with this module and protocol
Damotclese 0:387684ec9d92 113 // o Enter in to a forever loop which wakes up ten times a second
Damotclese 0:387684ec9d92 114 // o Drives the module's LED so that it flashes frim time to time
Damotclese 0:387684ec9d92 115 // to indicate that the thread is running
Damotclese 0:387684ec9d92 116 // o Check to ensure that the module has been initialized
Damotclese 0:387684ec9d92 117 // o If the module is initialized (and it should be) checks to
Damotclese 0:387684ec9d92 118 // see if there are inbound serial Modbus messages
Damotclese 0:387684ec9d92 119 // o Checks to see if there are any outbound serial Modbus messages
Damotclese 0:387684ec9d92 120 //
Damotclese 0:387684ec9d92 121 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 122 static void ModbusThread(void)
Damotclese 0:387684ec9d92 123 {
Damotclese 0:387684ec9d92 124 char ch_halfSecond = 5;
Damotclese 0:387684ec9d92 125
Damotclese 0:387684ec9d92 126 // Set the MODBUS LED to ON to indicate that the thread has started
Damotclese 0:387684ec9d92 127 st_digitalOutModbusLED = 1;
Damotclese 0:387684ec9d92 128
Damotclese 0:387684ec9d92 129 // Enter in to a forever loop
Damotclese 0:387684ec9d92 130 while (true)
Damotclese 0:387684ec9d92 131 {
Damotclese 0:387684ec9d92 132 // Sleep for one tenth of a second
Damotclese 0:387684ec9d92 133 wait(0.1);
Damotclese 0:387684ec9d92 134
Damotclese 0:387684ec9d92 135 // Count down the half second timer and see if it expired
Damotclese 0:387684ec9d92 136 if (0 == --ch_halfSecond)
Damotclese 0:387684ec9d92 137 {
Damotclese 0:387684ec9d92 138 // It has expired so restart the half second time
Damotclese 0:387684ec9d92 139 ch_halfSecond = 5;
Damotclese 0:387684ec9d92 140
Damotclese 0:387684ec9d92 141 // See if we turn on or turn off the LED
Damotclese 0:387684ec9d92 142 if (0 == c_flipFlop)
Damotclese 0:387684ec9d92 143 {
Damotclese 0:387684ec9d92 144 c_flipFlop = 1;
Damotclese 0:387684ec9d92 145 }
Damotclese 0:387684ec9d92 146 else
Damotclese 0:387684ec9d92 147 {
Damotclese 0:387684ec9d92 148 c_flipFlop = 0;
Damotclese 0:387684ec9d92 149 }
Damotclese 0:387684ec9d92 150
Damotclese 0:387684ec9d92 151 st_digitalOutModbusLED = c_flipFlop;
Damotclese 0:387684ec9d92 152 }
Damotclese 0:387684ec9d92 153
Damotclese 0:387684ec9d92 154 // We check to see if there is inbound or outbound serial traffic 10 times a second
Damotclese 0:387684ec9d92 155 if (TRUE == b_modbusInitialized)
Damotclese 0:387684ec9d92 156 {
Damotclese 0:387684ec9d92 157 // Check for inbound MODBUS frames
Damotclese 0:387684ec9d92 158 ModbusCheckInbound();
Damotclese 0:387684ec9d92 159
Damotclese 0:387684ec9d92 160 // See if we need to send outbound MODBUS frames
Damotclese 0:387684ec9d92 161 ModbusCheckOutbound();
Damotclese 0:387684ec9d92 162 }
Damotclese 0:387684ec9d92 163 }
Damotclese 0:387684ec9d92 164 }
Damotclese 0:387684ec9d92 165
Damotclese 0:387684ec9d92 166 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 167 // ModbusInit()
Damotclese 0:387684ec9d92 168 //
Damotclese 0:387684ec9d92 169 // This function will:
Damotclese 0:387684ec9d92 170 // o Initialize the module protocol's serial interface
Damotclese 0:387684ec9d92 171 // o Flag the fact that things are initialized
Damotclese 0:387684ec9d92 172 // o Launch the module's thread
Damotclese 0:387684ec9d92 173 //
Damotclese 0:387684ec9d92 174 // ----------------------------------------------------------------------
Damotclese 0:387684ec9d92 175 void ModbusInit(void)
Damotclese 0:387684ec9d92 176 {
Damotclese 0:387684ec9d92 177 // We configure the CPUM MODBUS serial interface
Damotclese 0:387684ec9d92 178 st_modbusSerial.baud(115200);
Damotclese 0:387684ec9d92 179 st_modbusSerial.format(8, SerialBase::None, 1);
Damotclese 0:387684ec9d92 180
Damotclese 0:387684ec9d92 181 // Flag the fact that the module has been initialized
Damotclese 0:387684ec9d92 182 b_modbusInitialized = true;
Damotclese 0:387684ec9d92 183
Damotclese 0:387684ec9d92 184 // Launch the CPUM Modbus thread
Damotclese 0:387684ec9d92 185 st_threadModbus.start(ModbusThread);
Damotclese 0:387684ec9d92 186 }
Damotclese 0:387684ec9d92 187
Damotclese 0:387684ec9d92 188 // End of file
Damotclese 0:387684ec9d92 189