Supachai Vorapojpisut
/
TAIST_modbus
Example code for modbus serial
Revision 1:0007712e84a8, committed 2018-03-16
- Comitter:
- vsupacha
- Date:
- Fri Mar 16 04:34:08 2018 +0000
- Parent:
- 0:f306cb0263a6
- Commit message:
- Draft of complete solution
Changed in this revision
--- a/main.cpp Wed Mar 14 06:17:48 2018 +0000 +++ b/main.cpp Fri Mar 16 04:34:08 2018 +0000 @@ -1,29 +1,84 @@ #include "mbed.h" #include "modbus.h" +#include "RawSerial.h" DigitalOut myled(LED1); RawSerial pc(USBTX, USBRX); +InterruptIn button(USER_BUTTON); +Ticker timebase; + +uint32_t Tick = 0; +uint32_t pressedTick = 0; +uint32_t releasedTick = 0; void serial_callback() { uint8_t frame[6]; + uint16_t offset, count; + uint8_t reg_map; char ch = pc.getc(); if (modbus_parser(ch, frame)) { - + offset = (frame[2] << 8) | (frame[3]); + count = (frame[4] << 8) | (frame[5]); + reg_map = modbus_check(offset, count); + modbus_response(reg_map); + } +} + +void pressed_callback() +{ + uint16_t skipCount; + + if ((Tick > pressedTick) && (Tick > releasedTick)) { + skipCount = Tick - releasedTick; + modbus_update(0x0000, skipCount); + pressedTick = Tick; + // printf("Pressed: %d - %d - %d\r\n", pressedTick, releasedTick, skipCount); } } +void released_callback() +{ + uint16_t widthCount; + + if ((Tick > pressedTick) && (Tick > releasedTick)) { + widthCount = Tick - pressedTick; + modbus_update(0x0001, widthCount); + releasedTick = Tick; + // printf("Released: %d - %d - %d\r\n", pressedTick, releasedTick, widthCount); + } +} + +void ticker_callback() +{ + Tick++; +} + int main() { // setup code - pc.attach(serial_callback); + pc.attach(&serial_callback); + // 1. button code + button.rise(&pressed_callback); + button.fall(&released_callback); + // 2. timer code + timebase.attach(&ticker_callback, 0.1); + printf("Starting\n"); + printf("Test: %02X\r\n", modbus_check(0x0000, 0x0001)); + printf("Test: %02X\r\n", modbus_check(0x0001, 0x0001)); + printf("Test: %02X\r\n", modbus_check(0x0000, 0x0002)); + printf("Test: %02X\r\n", modbus_check(0x0000, 0x0003)); + printf("Test: %02X\r\n", modbus_check(0x0001, 0x0002)); + printf("Test: %02X\r\n", modbus_check(0x0002, 0x0002)); while(1) { - // loop code - myled = 1; // LED is ON - wait(0.2); // 200 ms - myled = 0; // LED is OFF - wait(1.0); // 1 sec + // blinking LED + myled = !myled; + wait(2.5); + printf("Detection: %d - %d\r\n", pressedTick, releasedTick); + modbus_response(0x01); + modbus_response(0x02); + modbus_response(0x03); } }
--- a/modbus.cpp Wed Mar 14 06:17:48 2018 +0000 +++ b/modbus.cpp Fri Mar 16 04:34:08 2018 +0000 @@ -24,7 +24,8 @@ for (i = 0; i < 6; i++) { sum += frame[i]; } - if ((sum + lrc) == 0) { + sum = sum + lrc; + if (sum == 0) { status = 1; } } @@ -34,15 +35,20 @@ void modbus_init(uint8_t id) { + int i; + nodeId = id; + for (i = 0; i < ADDR_RANGE; i++) { + regValue[i] = 0; + } } uint16_t modbus_read(uint16_t offset) -{ +{ if (offset < ADDR_RANGE) { return regValue[offset]; } - return 0xFFFF; + return 0; } uint16_t modbus_update(uint8_t offset, uint16_t val) @@ -54,7 +60,23 @@ regValue[offset] = val; return tmp; } - return 0xFFFF; + return 0; +} + +uint8_t modbus_check(uint16_t offset, uint16_t count) +{ + uint8_t reg_map = 0x00; + int i, j; + + for (i = 0; i < ADDR_RANGE; i++) { + for (j = offset; j < (offset+count); j++) { + if (j == (ADDR_BASE + i)) { + reg_map |= (1 << i); + } + } + } + + return reg_map; } int modbus_parser(char ch, uint8_t *frame) @@ -72,6 +94,7 @@ } break; case RECEPTION: + printf("%c", ch); if ((ch >= '0') && (ch <= '9')) { buf[idx++] = ch; } else if ((ch >= 'a') && (ch <= 'f')) { @@ -101,3 +124,66 @@ return status; } + +uint8_t calc_lrc(uint8_t *frame, int count) +{ + int8_t lrc = 0; + int i; + + for (i = 0; i < count; i++) { + lrc += frame[i]; + } + return -lrc; +} + +void modbus_response(uint8_t reg_map) +{ + char fmt00[] = ":%02X%02X%02X\r\n"; + char fmt01[] = ":%02X%02X%02X%02X%02X\r\n"; + char fmt02[] = ":%02X%02X%02X%02X%02X\r\n"; + char fmt03[] = ":%02X%02X%02X%02X%02X%02X%02X\r\n"; + char *fmtstr; + char str[20]; + uint8_t frame[ADDR_RANGE*2 + 3]; + uint16_t tmp; + + frame[0] = nodeId; + frame[1] = FUNC_CODE; + switch(reg_map) { + case 1: + tmp = modbus_read(0); + frame[2] = tmp >> 8; + frame[3] = tmp & 0xFF; + frame[4] = calc_lrc(frame, 4); + fmtstr = fmt01; + sprintf(str, fmtstr, frame[0], frame[1], frame[2], frame[3], frame[4]); + printf("Response: %s", str); + break; + case 2: + tmp = modbus_read(1); + frame[2] = tmp >> 8; + frame[3] = tmp & 0xFF; + frame[4] = calc_lrc(frame, 4); + fmtstr = fmt02; + sprintf(str, fmtstr, frame[0], frame[1], frame[2], frame[3], frame[4]); + printf("Response: %s", str); + break; + case 3: + tmp = modbus_read(0); + frame[2] = tmp >> 8; + frame[3] = tmp & 0xFF; + tmp = modbus_read(1); + frame[4] = tmp >> 8; + frame[5] = tmp & 0xFF; + frame[6] = calc_lrc(frame, 6); + fmtstr = fmt03; + sprintf(str, fmtstr, frame[0], frame[1], frame[2], frame[3], frame[4], frame[5], frame[6]); + printf("Response: %s", str); + break; + default: + fmtstr = fmt00; + frame[2] = calc_lrc(frame, 2); + sprintf(str, fmtstr, frame[0], frame[1], frame[2]); + printf("Response: %s", str); + } +}
--- a/modbus.h Wed Mar 14 06:17:48 2018 +0000 +++ b/modbus.h Fri Mar 16 04:34:08 2018 +0000 @@ -10,5 +10,7 @@ uint16_t modbus_read(uint16_t offset); uint16_t modbus_update(uint8_t offset, uint16_t val); int modbus_parser(char ch, uint8_t *frame); +uint8_t modbus_check(uint16_t offset, uint16_t count); +void modbus_response(uint8_t reg_map); #endif // MODBUS_H