meta data for this page
Differences
This shows you the differences between two versions of the page.
— | arduino:code_collection [2025/08/23 21:57] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ~~NOCACHE~~ | ||
+ | ====== LamaPLC: Arduino code collection ====== | ||
+ | ===== Frequently used code collection ===== | ||
+ | ==== TON ==== | ||
+ | <code c> | ||
+ | // var def block | ||
+ | unsigned long startMillis, | ||
+ | const unsigned long period = 2000; // the value is a number of milliseconds | ||
+ | // code block | ||
+ | currentMillis = millis(); | ||
+ | if (currentMillis - startMillis >= period) | ||
+ | { | ||
+ | startMillis = currentMillis; | ||
+ | // after time has elapsed the call | ||
+ | // ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== check serial monitor ==== | ||
+ | <code c> | ||
+ | |||
+ | // code in setup() | ||
+ | Serial.begin(9600); | ||
+ | | ||
+ | while (!Serial) { | ||
+ | ; // wait for serial port to connect. Needed for native USB port only | ||
+ | } | ||
+ | Serial.println(" | ||
+ | </ | ||
+ | ===== Converting code collection ===== | ||
+ | ==== Float to char[] ==== | ||
+ | <code c> | ||
+ | // lib init (optional) | ||
+ | #include " | ||
+ | // converting | ||
+ | float a; | ||
+ | char sendValue[10]; | ||
+ | dtostrf (a, 10, 8, sendValue); // float_value, | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Int to char[] ==== | ||
+ | <code c> | ||
+ | int a; | ||
+ | char sendValue[10]; | ||
+ | itoa (i, | ||
+ | // base: Numerical base used to represent the value as a string, between 2 and 36, where 10 means decimal base, 16 hexadecimal, | ||
+ | |||
+ | </ | ||
+ | ==== String to char[] ==== | ||
+ | <code c> | ||
+ | |||
+ | char place[20]; | ||
+ | strcpy(place," | ||
+ | |||
+ | </ | ||
+ | ===== Modbus code collection ===== | ||
+ | ==== Convert 2 registers to float ==== | ||
+ | call: [float] = // | ||
+ | <code c> | ||
+ | float modbus_2regs_2_float(uint16_t a, uint16_t b) { | ||
+ | uint32_t combined = ((uint32_t)a << 16) | b; | ||
+ | float f; | ||
+ | memcpy(& | ||
+ | return f; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | call: [float] = // | ||
+ | |||
+ | <code c> | ||
+ | float modbus_2regs_2_float(uint16_t addr) { | ||
+ | uint16_t a = node.getResponseBuffer(addr); | ||
+ | uint16_t b = node.getResponseBuffer(addr+1); | ||
+ | uint32_t combined = ((uint32_t)a << 16) | b; | ||
+ | float f; | ||
+ | memcpy(& | ||
+ | return f; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Convert float 2 registers | ||
+ | def: int16_t regs[2]; \\ | ||
+ | call: // | ||
+ | back: register1: regs[1], register2: [regs[2] \\ | ||
+ | <code c> | ||
+ | void modbus_set_float(float f, uint16_t *dest) | ||
+ | { | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | Source: https:// | ||
+ | |||
+ | ==== Convert 2 registers to int32 ==== | ||
+ | <code c> | ||
+ | uint32_t make_32bit_word(uint16_t hi_word, uint16_t lo_word) | ||
+ | { | ||
+ | uint16_t words_16bit[2] = {hi_word, lo_word}; | ||
+ | uint32_t word_32bit = 0; | ||
+ | |||
+ | memcpy(& | ||
+ | |||
+ | return word_32bit; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | int32 convert direct to float by division by a thousand: \\ | ||
+ | |||
+ | <code c> | ||
+ | float make_float_32bit_word(uint16_t hi_word, uint16_t lo_word) | ||
+ | { | ||
+ | uint16_t words_16bit[2] = {hi_word, lo_word}; | ||
+ | uint32_t word_32bit = 0; | ||
+ | float back; | ||
+ | |||
+ | memcpy(& | ||
+ | back = word_32bit / 1000.0; | ||
+ | return back; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | call: [float] = // | ||
+ | |||
+ | <code c> | ||
+ | float make_float_32bit_word(uint16_t addr) | ||
+ | { | ||
+ | uint16_t words_16bit[2]; | ||
+ | words_16bit[1] = node.getResponseBuffer(addr); | ||
+ | words_16bit[0] = node.getResponseBuffer(addr+1); | ||
+ | uint32_t word_32bit = 0; | ||
+ | float back; | ||
+ | |||
+ | memcpy(& | ||
+ | back = word_32bit / 1000.0; | ||
+ | return back; | ||
+ | } | ||
+ | </ | ||
+ | ==== Float to / from one register ==== | ||
+ | <color red> | ||
+ | <code c> | ||
+ | // float 2 reg | ||
+ | holdingRegs[REG_HUM] = (int16_t)(Humidity * 100); | ||
+ | // back one reg to float | ||
+ | float Humidity = holdingRegs[REG_HUM] / 100.0; | ||
+ | </ | ||
+ | |||
+ | ==== Modbus #define conversions ==== | ||
+ | <code c> | ||
+ | #define MODBUS_GET_HIGH_BYTE(data) (((data) >> 8) & 0xFF) | ||
+ | #define MODBUS_GET_LOW_BYTE(data) | ||
+ | #define MODBUS_GET_INT64_FROM_INT16(tab_int16, | ||
+ | (((int64_t) tab_int16[(index)] << 48) | ((int64_t) tab_int16[(index) + 1] << 32) | \ | ||
+ | | ||
+ | #define MODBUS_GET_INT32_FROM_INT16(tab_int16, | ||
+ | (((int32_t) tab_int16[(index)] << 16) | (int32_t) tab_int16[(index) + 1]) | ||
+ | #define MODBUS_GET_INT16_FROM_INT8(tab_int8, | ||
+ | (((int16_t) tab_int8[(index)] << 8) | (int16_t) tab_int8[(index) + 1]) | ||
+ | #define MODBUS_SET_INT16_TO_INT8(tab_int8, | ||
+ | do { \ | ||
+ | ((int8_t *) (tab_int8))[(index)] = (int8_t) ((value) >> 8); \ | ||
+ | ((int8_t *) (tab_int8))[(index) + 1] = (int8_t) (value); | ||
+ | } while (0) | ||
+ | #define MODBUS_SET_INT32_TO_INT16(tab_int16, | ||
+ | do { \ | ||
+ | ((int16_t *) (tab_int16))[(index)] = (int16_t) ((value) >> 16); \ | ||
+ | ((int16_t *) (tab_int16))[(index) + 1] = (int16_t) (value); | ||
+ | } while (0) | ||
+ | #define MODBUS_SET_INT64_TO_INT16(tab_int16, | ||
+ | do { \ | ||
+ | ((int16_t *) (tab_int16))[(index)] = (int16_t) ((value) >> 48); \ | ||
+ | ((int16_t *) (tab_int16))[(index) + 1] = (int16_t) ((value) >> 32); \ | ||
+ | ((int16_t *) (tab_int16))[(index) + 2] = (int16_t) ((value) >> 16); \ | ||
+ | ((int16_t *) (tab_int16))[(index) + 3] = (int16_t) (value); | ||
+ | } while (0) | ||
+ | </ | ||
+ | |||
+ | ==== Modbus messages ==== | ||
+ | <code c> | ||
+ | bool getResultMsg(uint8_t result) | ||
+ | { | ||
+ | String tmpstr2; | ||
+ | |||
+ | switch (result) { | ||
+ | case node.ku8MBSuccess: | ||
+ | return true; | ||
+ | break; | ||
+ | case node.ku8MBIllegalFunction: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | case node.ku8MBIllegalDataAddress: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | case node.ku8MBIllegalDataValue: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | case node.ku8MBSlaveDeviceFailure: | ||
+ | tmpstr2 = "Slave Device Failure"; | ||
+ | break; | ||
+ | case node.ku8MBInvalidSlaveID: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | case node.ku8MBInvalidFunction: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | case node.ku8MBResponseTimedOut: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | case node.ku8MBInvalidCRC: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | default: | ||
+ | tmpstr2 = " | ||
+ | break; | ||
+ | } | ||
+ | Serial.println(tmpstr2); | ||
+ | return false; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== General code collection ===== | ||
+ | ==== MAC random generator ==== | ||
+ | Generate random MAC using pseudo random generator, bytes 0, 1 and 2 are static (MAC_START), | ||
+ | <code c> | ||
+ | void generateMac() { | ||
+ | // Marsaglia algorithm from https:// | ||
+ | seed1 = 36969L * (seed1 & 65535L) + (seed1 >> 16); | ||
+ | seed2 = 18000L * (seed2 & 65535L) + (seed2 >> 16); | ||
+ | uint32_t randomBuffer = (seed1 << 16) + seed2; /* 32-bit random */ | ||
+ | memcpy(data.mac, | ||
+ | for (byte i = 0; i < 3; i++) { | ||
+ | data.mac[i + 3] = randomBuffer & 0xFF; // random last 3 bytes | ||
+ | randomBuffer >>= 8; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | This page has been accessed for: Today: {{counter|today}}, |