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
Plot of the initial start-up canned AC and DC spectra.
NextGen-Exerciser-Modbus.cpp
- Committer:
- Damotclese
- Date:
- 2019-05-31
- Revision:
- 2:346119b3db6c
- Parent:
- 0:387684ec9d92
File content as of revision 2:346119b3db6c:
// ---------------------------------------------------------------------- // 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