34 AllWize::AllWize(HardwareSerial * serial, uint8_t reset_gpio) : _stream(serial), _hw_serial(serial), _reset_gpio(reset_gpio) {
43 #if not defined(ARDUINO_ARCH_SAMD) && not defined(ARDUINO_ARCH_ESP32) 44 AllWize::AllWize(SoftwareSerial * serial, uint8_t reset_gpio) : _stream(serial), _sw_serial(serial), _reset_gpio(reset_gpio) {
55 AllWize::AllWize(uint8_t rx, uint8_t tx, uint8_t reset_gpio) : _rx(rx), _tx(tx), _reset_gpio(reset_gpio) {
56 #if defined(ARDUINO_ARCH_SAMD) 59 #elif defined(ARDUINO_ARCH_ESP32) 60 _stream = _hw_serial =
new HardwareSerial(HARDWARE_SERIAL_PORT);
62 _stream = _sw_serial =
new SoftwareSerial(_rx, _tx);
67 void AllWize::_init() {
68 if (GPIO_NONE != _reset_gpio) {
69 pinMode(_reset_gpio, OUTPUT);
70 digitalWrite(_reset_gpio, HIGH);
72 randomSeed(analogRead(0));
73 _access_number = random(0,256);
82 _append_rssi =
_getMemory(MEM_RSSI_MODE) == 0x01;
84 _data_interface =
_getMemory(MEM_DATA_INTERFACE);
95 #if defined(ARDUINO_ARCH_ESP32) 96 if ((_rx != -1) && (_tx != -1)) {
97 pinMode(_rx, FUNCTION_4);
98 pinMode(_tx, FUNCTION_4);
99 _hw_serial->begin(MODEM_BAUDRATE, SERIAL_8N1, _rx, _tx);
101 _hw_serial->begin(MODEM_BAUDRATE);
104 _hw_serial->begin(MODEM_BAUDRATE);
109 #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) 114 _sw_serial->begin(MODEM_BAUDRATE);
128 if (GPIO_NONE == _reset_gpio) {
143 digitalWrite(_reset_gpio, LOW);
145 digitalWrite(_reset_gpio, HIGH);
179 setMode(DEFAULT_MBUS_MODE,
true);
193 setMode(DEFAULT_MBUS_MODE,
true);
203 setMode(DEFAULT_MBUS_MODE,
true);
236 uint32_t start = millis();
237 while (millis() - start < timeout) {
238 if (
ready())
return true;
251 _send(CMD_TEST_MODE_0);
257 char ascii[17] = {0};
262 for (uint16_t address = 0; address <= 0x0F; address++) {
263 snprintf(ch,
sizeof(ch),
"%02X ", address);
267 debug.print(
"------------------------------------------------------");
269 for (uint16_t address = 0; address <= 255; address++) {
270 if ((address % 16) == 0) {
271 if (address > 0) debug.print(ascii);
272 snprintf(ch,
sizeof(ch),
"\n0x%02X: ", address);
275 if (31 < buffer[address] && buffer[address] < 127) {
276 ascii[address % 16] = (char) buffer[address];
278 ascii[address % 16] =
' ';
280 snprintf(ch,
sizeof(ch),
"%02X ", (uint8_t) buffer[address]);
288 debug.println(
"Error doing memory dump...");
303 if (_config)
return false;
304 if (0 == len)
return (1 ==
_send(0xFE));
307 if (1 !=
_send(len+1))
return false;
310 if (1 !=
_send(_ci))
return false;
313 if (len !=
_send(buffer, len))
return false;
326 return send((uint8_t *) buffer, strlen(buffer));
336 bool response =
false;
340 static uint32_t when = millis();
342 while (_stream->available() && _pointer < RX_BUFFER_SIZE) {
343 uint8_t ch = _stream->read();
344 _buffer[_pointer++] = ch;
346 #if defined(ARDUINO_ARCH_ESP8266) 352 if ((_pointer > 0) && (millis() - when > 100)) {
417 if (0 < power && power < 6) {
438 if (0 < dr && dr < 6 && dr != 3) {
498 _append_rssi = value;
514 if (PREAMBLE_FORMAT_A == preamble || PREAMBLE_FORMAT_B == preamble) {
582 _data_interface = value;
591 return _data_interface;
641 if (0 == flag || 1 == flag || 3 == flag) {
642 _encrypt = (flag & 0x01) == 0x01;
677 if (0 < reg && reg < 65) {
680 memcpy(&data[1], key, 16);
690 _setMemory(MEM_DEFAULT_KEY, (uint8_t *) key, 16);
725 ret_val = _buffer[0] - 128;
741 ret_val = 30 * _buffer[0];
763 buffer[0] = (mid >> 8) & 0xFF;
764 buffer[1] = (mid >> 0) & 0xFF;
765 return _setMemory(MEM_MANUFACTURER_ID, buffer, 2);
782 buffer[0] = (uid >> 24) & 0xFF;
783 buffer[1] = (uid >> 16) & 0xFF;
784 buffer[2] = (uid >> 8) & 0xFF;
785 buffer[3] = (uid >> 0) & 0xFF;
851 if (value != _config) {
859 _send(CMD_EXIT_CONFIG);
875 int8_t response = -1;
892 int8_t response = -1;
908 int8_t response = -1;
924 uint8_t buffer[len*2+1];
925 for (uint8_t i=0; i<len; i++) {
926 buffer[i*2] = address + i;
927 buffer[i*2+1] = data[i];
929 buffer[len*2] = CMD_EXIT_MEMORY;
930 return (
_sendCommand(CMD_WRITE_MEMORY, buffer, len*2+1) != -1);
941 uint8_t buffer[3] = {address, value, (uint8_t) CMD_EXIT_MEMORY};
942 return (
_sendCommand(CMD_WRITE_MEMORY, buffer, 3) != -1);
956 for (uint8_t i=0; i<len; i++) {
960 buffer[i] = _buffer[0];
974 uint8_t response =
_sendCommand(CMD_READ_MEMORY, address);
975 if (response > 0)
return _buffer[0];
1008 memcpy(hex, bin, len);
1019 if (_model.length() > 0)
return;
1021 if (line.indexOf(
"RC") != 0) String line =
_getMemoryAsString(MEM_PART_NUMBER_OLD, 32);
1023 if (line.indexOf(
"RC") != 0) {
1024 _model = String(
"Unknown");
1029 uint8_t end = line.indexOf(
",", start);
1030 _model = line.substring(start, end);
1033 end = line.indexOf(
",", start);
1034 _hw = line.substring(start, end);
1037 end = line.indexOf(
",", start);
1038 _fw = line.substring(start, end);
1073 #if defined(ALLWIZE_DEBUG_PORT) 1076 ALLWIZE_DEBUG_PRINT(
"recv:");
1077 for (uint8_t i = 0; i < _pointer; i++) {
1078 snprintf(ch,
sizeof(ch),
" %02X", _buffer[i]);
1079 ALLWIZE_DEBUG_PRINT(ch);
1081 ALLWIZE_DEBUG_PRINTLN();
1086 uint8_t _local[RX_BUFFER_SIZE];
1087 memcpy(_local, _buffer, RX_BUFFER_SIZE);
1090 uint8_t mbus_mode =
getMode();
1092 bool has_start = (data_interface & 0x04) == 0x04;
1093 bool has_header = (mbus_mode != MBUS_MODE_OSP) & ((data_interface & 0x01) == 0x00);
1095 bool has_crc = (data_interface & 0x08) == 0x08;
1096 uint8_t bytes_not_in_len = has_start ? 3 : 1;
1097 uint8_t bytes_not_in_app = (has_header ? 9 : 0) + 1 + (has_rssi ? 1 : 0) + (has_crc ? 2 : 0);
1104 if (START_BYTE != _local[in])
return false;
1109 uint8_t len = _local[in];
1110 if (_pointer != len + bytes_not_in_len)
return false;
1116 _message.c = _local[in];
1120 unsigned int man = (_local[in+1] << 8) + _local[in];
1121 _message.man[0] = ((man >> 10) & 0x001F) + 64;
1122 _message.man[1] = ((man >> 5) & 0x001F) + 64;
1123 _message.man[2] = ((man >> 0) & 0x001F) + 64;
1124 _message.man[3] = 0;
1128 _message.address[0] = _local[in + 3];
1129 _message.address[1] = _local[in + 2];
1130 _message.address[2] = _local[in + 1];
1131 _message.address[3] = _local[in + 0];
1134 _message.type = _local[in + 5];
1137 _message.version = _local[in + 4];
1144 _message.version = 0;
1145 _message.man[0] = 0;
1146 memset(_message.address, 0, 6);
1150 _message.ci = _buffer[in];
1154 _message.len = len - bytes_not_in_app;
1155 memcpy(_message.data, &_local[in], _message.len);
1156 _message.data[_message.len] = 0;
1161 _message.rssi = _local[in];
1164 _message.rssi = 0xFF;
1174 if (STOP_BYTE != _local[in])
return false;
1198 #if defined(ALLWIZE_DEBUG_PORT) 1201 snprintf(buffer,
sizeof(buffer),
"w %02X", ch);
1202 ALLWIZE_DEBUG_PRINTLN(buffer);
1205 return _stream->write(ch);
1217 for (uint8_t i=0; i<len; i++) {
1218 if (
_send(buffer[i])) n++;
1229 return _readBytesUntil(END_OF_RESPONSE, (
char*) _buffer, RX_BUFFER_SIZE);
1240 if (
_send(buffer, len) != len)
return -1;
1251 if (
_send(ch) != 1)
return -1;
1265 uint32_t _start = millis();
1266 while (millis() - _start < _timeout) {
1267 int ch = _stream->read();
1268 if (ch >= 0)
return ch;
1269 #if defined(ARDUINO_ARCH_ESP8266) 1284 if (len < 1)
return 0;
1286 while (index < len) {
1290 #if defined(ALLWIZE_DEBUG_PORT) 1293 snprintf(buffer,
sizeof(buffer),
"r %02X", ch);
1294 ALLWIZE_DEBUG_PRINTLN(buffer);
1298 *buffer++ = (char) ch;
1313 if (len < 1)
return 0;
1315 while (index < len) {
1319 if (ch == terminator)
break;
1321 #if defined(ALLWIZE_DEBUG_PORT) 1324 snprintf(buffer,
sizeof(buffer),
"r %02X", ch);
1325 ALLWIZE_DEBUG_PRINTLN(buffer);
1329 *buffer++ = (char) ch;
1343 for (uint8_t i=0; i<len; i+=2) {
1344 bin[i/2] = ((hex[i] -
'0') * 16 + (hex[i+1] -
'0')) & 0xFF;
1356 for (uint8_t i=0; i<len; i++) {
1357 sprintf(&hex[i*2],
"%02X", bin[i]);
uint8_t getChannel()
Gets the channel stored in non-volatile memory.
void setInstallMode(uint8_t mode, bool persist=false)
Sets the module in one of the available operations modes.
bool setUID(uint32_t uid)
Saved the UID into the module memory uid UID to save.
void setEncryptFlag(uint8_t flag)
Sets the encrypt flag setting.
uint8_t getSleepMode()
Gets the sleep mode stored in non-volatile memory.
uint8_t getLEDControl()
Gets the current LED control.
uint8_t getPower()
Gets the RF power stored in non-volatile memory.
int _readBytes(char *buffer, uint16_t len)
Reads the stream buffer up to a number of bytes.
bool _setMemory(uint8_t address, uint8_t *data, uint8_t len)
Sets non-volatile memory contents starting from given address.
uint8_t getEncryptFlag()
Gets the encrypt flag setting.
AllWize(HardwareSerial *serial, uint8_t reset_gpio=GPIO_NONE)
AllWize object constructor.
void slave()
Sets the module in slave mode.
void setPower(uint8_t power, bool persist=false)
Sets the RF power.
void setNetworkRole(uint8_t role)
Sets the network role.
String _getMemoryAsHexString(uint8_t address, uint8_t len)
Returns the contents of the memory from a certain address as an HEX String.
bool getAppendRSSI()
Gets the current RSSI mode value.
bool _decode()
Decodes the current RX buffer contents.
uint8_t getVersion()
Returns the module version from non-volatile memory.
void setControlField(uint8_t value, bool persist=false)
Sets the control field value.
int8_t _sendCommand(uint8_t command, uint8_t *data, uint8_t len)
Sends a command with the given data.
void dump(Stream &debug)
Dumps the current memory configuration to the given stream.
void setMode(uint8_t mode, bool persist=false)
Sets the module in one of the available MBus modes.
void setPreamble(uint8_t preamble)
Sets the preamble length frame format.
uint8_t getControlField()
Gets the control field value stored in non-volatile memory.
uint8_t getTimeout()
Gets the current timeout for auto sleep modes.
uint8_t getPreamble()
Gets the preamble length frame format.
int8_t _receive()
Listens to incomming data from the module until timeout or END_OF_RESPONSE.
bool send(uint8_t *buffer, uint8_t len)
Sends a byte array.
String getUID()
Returns the Unique ID string.
uint8_t getTemperature()
Returns the RSSI of the last valid packet received TODO: values do not seem right and are not the sam...
bool ready()
Test whether the radio module is ready or not.
void setSleepMode(uint8_t mode)
Sets the sleep mode.
uint8_t getDecryptFlag()
Gets the decrypt flag setting.
void setControlInformation(uint8_t ci)
Sets the control information byte.
void wakeup()
Wakes up the radio from sleep mode.
void master()
Sets the module in master mode.
bool available()
Returns true if a new message has been received and decoded This method has to be called in the main ...
uint8_t getDevice()
Returns the device version from non-volatile memory.
void setLEDControl(uint8_t value)
Sets the LED control.
int8_t _sendAndReceive(uint8_t *buffer, uint8_t len)
Sends a binary buffer and waits for response. Returns the number of bytes received and stored in the ...
void setTimeout(uint8_t timeout)
Sets the timeout for auto sleep modes.
uint8_t _getMemory(uint8_t address, uint8_t *buffer, uint8_t len)
Returns the contents of consecutive memory addresses.
void setDecryptFlag(uint8_t flag)
Sets the decrypt flag setting.
String getPartNumber()
Returns the module part number.
void _reset_serial()
Resets the serial object.
void repeater()
Sets the module in repeater mode.
bool waitForReady(uint32_t timeout=DEFAULT_TIMEOUT)
Waits for timeout millis for the module to be ready.
uint8_t getNetworkRole()
Gets the current network role.
uint8_t getMode()
Gets the MBus mode stored in non-volatile memory.
int _readBytesUntil(char terminator, char *buffer, uint16_t len)
Reads the stream buffer up to a certain char or times out.
void sleep()
Sets the radio module in sleep mode.
String getFirmwareVersion()
Returns the module firmware revision.
bool _setConfig(bool value)
Sets or unsets config mode.
String getMID()
Returns the Manufacturer ID string.
void setChannel(uint8_t channel, bool persist=false)
Sets the communications channel (for MBUS_MODE_R2 only)
void setAppendRSSI(bool value)
Sets the RSSI mode value.
String getSerialNumber()
Returns the module serial number.
void getDefaultKey(uint8_t *key)
Gets the default encryption key.
String _getMemoryAsString(uint8_t address, uint8_t len)
Returns the contents of the memory from a certain address as a String object.
void _readModel()
Reads and caches the module model & version.
uint8_t getControlInformation()
Gets the control information byte.
void setDataInterface(uint8_t value)
Sets the data interface for receiving packets.
int _timedRead()
Reads a byte from the stream with a timeout.
void setKey(uint8_t reg, const uint8_t *key)
Sets the default encryption key.
void setDefaultKey(const uint8_t *key)
Sets the default encryption key.
uint8_t getInstallMode()
Gets the install modevalue stored in non-volatile memory.
bool reset()
Resets the radio module.
bool setMID(uint16_t mid)
Sets the Manufacturer ID mid MID to save.
String getRequiredHardwareVersion()
Returns the module hardware revision.
void _bin2hex(uint8_t *bin, char *hex, uint8_t len)
Converts a binary buffer to an hex c-string.
uint8_t _send(uint8_t *buffer, uint8_t len)
Sends a binary buffer to the module UART. Returns the number of bytes actually sent.
void begin()
Inits the module communications.
void _hex2bin(char *hex, uint8_t *bin, uint8_t len)
Converts a hex c-string to a binary buffer.
void _flush()
Flushes the serial line to the module.
uint8_t getDataInterface()
Gets the data interface for receiving packets.
void setDataRate(uint8_t dr)
Sets the data rate.
uint8_t getDataRate()
Gets the data rate stored in non-volatile memory.
allwize_message_t read()
Returns latest received message.
uint16_t getVoltage()
Returns the internal voltage of the module.
bool factoryReset()
Resets the module to factory settings.