-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #62 from Tinyu-Zhao/master
Add some examples
- Loading branch information
Showing
86 changed files
with
28,524 additions
and
2,018 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
******************************************************************************* | ||
* Copyright (c) 2021 by M5Stack | ||
* Equipped with M5Core2 sample source code | ||
* 配套 M5Core2 示例源代码 | ||
* Visit the website for more information:https://docs.m5stack.com/en/products | ||
* 获取更多资料请访问:https://docs.m5stack.com/zh_CN/products | ||
* | ||
* describe: AC Socket. | ||
* date:2021/9/1 | ||
******************************************************************************* | ||
Click button B to turn on the power. Click button A to turn off the power. | ||
单击按钮 B 打开电源。 单击按钮 A 关闭电源。 | ||
*/ | ||
#include <Arduino.h> | ||
#include <M5Core2.h> | ||
#include "protocol.h" | ||
#include "modbus.h" | ||
volatile uint32_t tim = 0; | ||
|
||
uint32_t time_now = 0; | ||
uint8_t ucTestFlag = 0; | ||
bool ubCoilState = false; | ||
|
||
void setup() { | ||
M5.begin(true, false, true, false, kMBusModeOutput); | ||
mb_init(0xac, 9600, &tim); | ||
Serial1.begin(9600, SERIAL_8N1, 13, 14); | ||
time_now = millis(); | ||
// put your setup code here, to run once: | ||
} | ||
|
||
|
||
void loop() { | ||
M5.update(); | ||
|
||
if(millis() - time_now > 60000UL) { | ||
time_now = millis(); | ||
if(ucTestFlag) { | ||
if(ubCoilState) { | ||
char data_str[] = {0xAA, 5, 0x00, 0x00, 0x00, 0x00}; | ||
mb_send_frame((uint8_t *)data_str, 6); | ||
} else { | ||
char data_str[] = {0xAA, 5, 0x00, 0x00, 0xff, 0x00}; | ||
mb_send_frame((uint8_t *)data_str, 6); | ||
} | ||
ubCoilState = 1 - ubCoilState; | ||
} | ||
} | ||
|
||
if(M5.BtnA.wasPressed()) { | ||
char data_str[] = {0xAA, 5, 0x00, 0x00, 0x00, 0x00}; | ||
mb_send_frame((uint8_t *)data_str, 6); | ||
} | ||
|
||
if(M5.BtnB.wasPressed()) { | ||
char data_str[] = {0xAA, 5, 0x00, 0x00, 0xff, 0x00}; | ||
mb_send_frame((uint8_t *)data_str, 6); | ||
} | ||
|
||
|
||
if(M5.BtnC.wasPressed()) { | ||
ucTestFlag = 1 - ucTestFlag; | ||
} | ||
|
||
vTaskDelay(pdMS_TO_TICKS(10)); | ||
|
||
// while(Serial1.available()) { | ||
// protocol_rec_put(Serial1.read()); | ||
// micros(); | ||
// } | ||
// put your main code here, to run repeatedly: | ||
} | ||
|
||
void mb_send_one_byte(uint8_t data) { | ||
Serial1.write(data); | ||
} | ||
|
||
void protocol_callback(CmdData cmd) { | ||
Serial.printf("got ... \r\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#include "modbus.h" | ||
|
||
typedef enum | ||
{ | ||
STATE_RX_INIT, /*!< Receiver is in initial state. */ | ||
STATE_RX_IDLE, /*!< Receiver is in idle state. */ | ||
STATE_RX_RCV, /*!< Frame is beeing received. */ | ||
STATE_RX_ERROR /*!< If the frame is invalid. */ | ||
} eMBRcvState; | ||
|
||
typedef enum { | ||
STATE_TX_IDLE, /*!< Transmitter is in idle state. */ | ||
STATE_TX_XMIT /*!< Transmitter is in transfer state. */ | ||
} eMBSndState; | ||
|
||
/* ----------------------- Static variables ---------------------------------*/ | ||
static volatile eMBSndState eSndState; | ||
static volatile eMBRcvState eRcvState; | ||
static uint8_t ucMbId; | ||
static uint16_t usframeT35_50us; | ||
volatile uint32_t *puiTimeTicks; | ||
volatile uint32_t usFrameIdleTicks; | ||
static volatile uint8_t ucMasterRTURcvBuf[MB_SER_PDU_SIZE_MAX]; | ||
static volatile uint16_t usRcvBuffPos; | ||
|
||
static const uint8_t aucCRCHi[] = { | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, | ||
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, | ||
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, | ||
0x00, 0xC1, 0x81, 0x40 | ||
}; | ||
|
||
static const uint8_t aucCRCLo[] = { | ||
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, | ||
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, | ||
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, | ||
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, | ||
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, | ||
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, | ||
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, | ||
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, | ||
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, | ||
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, | ||
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, | ||
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, | ||
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, | ||
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, | ||
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, | ||
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, | ||
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, | ||
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, | ||
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, | ||
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, | ||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, | ||
0x41, 0x81, 0x80, 0x40 | ||
}; | ||
|
||
uint16_t usMBCRC16(uint8_t * pucFrame, uint16_t usLen) { | ||
uint8_t ucCRCHi = 0xFF; | ||
uint8_t ucCRCLo = 0xFF; | ||
int iIndex; | ||
|
||
while (usLen--) { | ||
iIndex = ucCRCLo ^ *(pucFrame++); | ||
ucCRCLo = (uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]); | ||
ucCRCHi = aucCRCLo[iIndex]; | ||
} | ||
return (uint16_t)(ucCRCHi << 8 | ucCRCLo); | ||
} | ||
|
||
void mb_init(uint8_t id, uint32_t boudrate, volatile uint32_t * time_base) { | ||
ucMbId = id; | ||
puiTimeTicks = time_base; | ||
if (boudrate > 19200) { | ||
usframeT35_50us = 35; | ||
} else { | ||
usframeT35_50us = (7UL * 220000UL) / (2UL * boudrate); | ||
} | ||
} | ||
|
||
void mb_put_rec_data(uint8_t data) { | ||
usFrameIdleTicks = *puiTimeTicks; | ||
ucMasterRTURcvBuf[usRcvBuffPos++] = data; | ||
if (usRcvBuffPos == MB_SER_PDU_SIZE_MAX) { | ||
mb_get_frame_error_cb(MB_EIO); | ||
usRcvBuffPos = 0; | ||
} | ||
} | ||
|
||
void mb_poll() { | ||
if ((uint16_t)*puiTimeTicks - usframeT35_50us > usFrameIdleTicks) { | ||
if (usRcvBuffPos > MB_SER_PDU_SIZE_MIN && usMBCRC16((uint8_t *)ucMasterRTURcvBuf, usRcvBuffPos) == 0) { | ||
mb_get_frame_cb(ucMasterRTURcvBuf[0], (uint8_t *)ucMasterRTURcvBuf, usRcvBuffPos - 2 - 1); | ||
usRcvBuffPos = 0; | ||
} else if (usRcvBuffPos > 0) { | ||
mb_get_frame_error_cb(MB_EIO); | ||
usRcvBuffPos = 0; | ||
} | ||
} | ||
} | ||
|
||
void mb_send_frame(uint8_t* frame, uint16_t length) { | ||
uint16_t usCRC16; | ||
uint8_t frame_out[length + 2]; | ||
memcpy(frame_out, frame, length); | ||
usCRC16 = usMBCRC16(frame, length); | ||
frame_out[length] = (uint8_t)(usCRC16 & 0xff); | ||
frame_out[length+1] = (uint8_t)(usCRC16 >> 8); | ||
for (uint16_t i = 0; i < length + 2; i++) { | ||
mb_send_one_byte(frame_out[i]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#pragma once | ||
#ifndef __MODBUS__H_ | ||
#define __MODBUS__H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include "Arduino.h" | ||
|
||
#define MB_ID 0xAA | ||
|
||
/* ----------------------- Defines ------------------------------------------*/ | ||
#define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */ | ||
#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */ | ||
#define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */ | ||
#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */ | ||
#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */ | ||
|
||
#define MB_ADDRESS_BROADCAST ( 0 ) /*! Modbus broadcast address. */ | ||
#define MB_ADDRESS_MIN ( 1 ) /*! Smallest possible slave address. */ | ||
#define MB_ADDRESS_MAX ( 247 ) /*! Biggest possible slave address. */ | ||
|
||
#define MB_FUNC_NONE ( 0 ) | ||
#define MB_FUNC_READ_COILS ( 1 ) | ||
#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 ) | ||
#define MB_FUNC_WRITE_SINGLE_COIL ( 5 ) | ||
#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 ) | ||
#define MB_FUNC_READ_HOLDING_REGISTER ( 3 ) | ||
#define MB_FUNC_READ_INPUT_REGISTER ( 4 ) | ||
#define MB_FUNC_WRITE_REGISTER ( 6 ) | ||
#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 ) | ||
#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 ) | ||
#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 ) | ||
#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 ) | ||
#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 ) | ||
#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 ) | ||
#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 ) | ||
#define MB_FUNC_ERROR ( 128 ) | ||
|
||
enum MB_FC { | ||
MB_FC_NONE = 0, /*!< null operator */ | ||
MB_FC_READ_COILS = 1, /*!< FCT=1 -> read coils or digital outputs */ | ||
MB_FC_READ_DISCRETE_INPUT = 2, /*!< FCT=2 -> read digital inputs */ | ||
MB_FC_READ_REGISTERS = 3, /*!< FCT=3 -> read registers or analog outputs */ | ||
MB_FC_READ_INPUT_REGISTER = 4, /*!< FCT=4 -> read analog inputs */ | ||
MB_FC_WRITE_COIL = 5, /*!< FCT=5 -> write single coil or output */ | ||
MB_FC_WRITE_REGISTER = 6, /*!< FCT=6 -> write single register */ | ||
MB_FC_WRITE_MULTIPLE_COILS = 15, /*!< FCT=15 -> write multiple coils or outputs */ | ||
MB_FC_WRITE_MULTIPLE_REGISTERS = 16 /*!< FCT=16 -> write multiple registers */ | ||
}; | ||
|
||
enum MB_STATUS { | ||
MB_OK = 0, | ||
MB_FRAME = -1, | ||
MB_BUFF_OVERFLOW = -2, | ||
MB_CRC_ERROR = -3, | ||
}; | ||
|
||
typedef enum { | ||
MB_ENOERR, /*!< no error. */ | ||
MB_ENOREG, /*!< illegal register address. */ | ||
MB_EINVAL, /*!< illegal argument. */ | ||
MB_EPORTERR, /*!< porting layer error. */ | ||
MB_ENORES, /*!< insufficient resources. */ | ||
MB_EIO, /*!< I/O error. */ | ||
MB_EILLSTATE, /*!< protocol stack in illegal state. */ | ||
MB_ETIMEDOUT /*!< timeout error occurred. */ | ||
} eMBErrorCode; | ||
|
||
void mb_put_rec_data(uint8_t data); | ||
void mb_init(uint8_t id, uint32_t boudrate, volatile uint32_t * time_base); | ||
void mb_poll(); | ||
void mb_send_frame(uint8_t *frame, uint16_t length); | ||
|
||
__attribute__((weak)) void mb_send_one_byte(uint8_t data); | ||
__attribute__((weak)) void mb_get_frame_cb(uint8_t rcvAddress, uint8_t *frame, uint16_t length); | ||
__attribute__((weak)) void mb_get_frame_error_cb(eMBErrorCode); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
Oops, something went wrong.