Насколько я понял master.poll() является асинхронной операцией, поэтому важно делать так, как написано в примерах. Асинхронность означает, что функция возвращает управление сразу, а не ожидает завершения какой-то операции.
Насколько я понял master.poll() является асинхронной операцией, поэтому важно делать так, как написано в примерах. Асинхронность означает, что функция возвращает управление сразу, а не ожидает завершения какой-то операции.
может и асинхронна, не знаю, ок, попробую и строго по примерам. Спасибо
Судя по всему не так. У вас получается случайная каша, на которую я не обратил внимания, т.к. не видел примеров использования класса в режиме мастера. Метод poll() должен вызываться постоянно, а не однократно. И каждый раз нужно следить за переменной внутреннего состояния. Т.е. нужно дать задание и потом непрерывно "дергать" объект, проверяя не пришло ли чего. В вашем случае звёзды совпали только частично.
Ну и не обязательно делать 2 запроса. Вполне можно обойтись и одним, запрашивая 2 регистра, но также как в примерах.
Проверил на установке - данные шлем и получаем! Ура!
Теперь беда с отображением полученных данных на экране. Для этого в 56 и 57 явно подставил значения и надеялся получить на экране что нить типа 0.00007656 или 7.656е-005 но дает 0.00
Вариант lcd.print(data.fvalue*100000); единственный для получения результата или можно без умножения?
Посмотрите как реализованы мастеры в примерах к библиотеке и сделайте также. Там применяется автомат состояний через использование case'ов.
void loop() { switch( u8state ) { case 0: if (millis() > u32wait) u8state++; // wait state break; case 1: telegram.u8id = 1; // slave address telegram.u8fct = 3; // function code (this one is registers read) telegram.u16RegAdd = 1; // start address in slave telegram.u16CoilsNo = 4; // number of elements (coils or registers) to read telegram.au16reg = au16data; // pointer to a memory array in the Arduino master.query( telegram ); // send query (only once) u8state++; break; case 2: master.poll(); // check incoming messages if (master.getState() == COM_IDLE) { u8state = 0; u32wait = millis() + 100; } break; } }Для нескольких запросов там есть расширенный пример.
Там применяется автомат состояний через использование case'ов.
а смысл этого? По шагам:1 - ждем нужное время 2 - делаем запрос на чтение 3- смотрим что там пришло
Т.е. фактически через равные промежутки времени делаем запрос и читаем ответ.
Если помните первые мои образцы скетчов так и строились. Может чего не понимаю, но логика от этого не меняется
Для нескольких запросов там есть расширенный пример.
сейчас гляну...
Насколько я понял master.poll() является асинхронной операцией, поэтому важно делать так, как написано в примерах. Асинхронность означает, что функция возвращает управление сразу, а не ожидает завершения какой-то операции.
про несколько запросов - логика вроде такая:
case 0 ждем 1000мс
case 1 шлем запрос telegram[0]
case 2 обрабатываем ответ
case 0 ждем 1000мс
case 1 шлем запрос telegram[1]
case 2 обрабатываем ответ
и т.д.
У меня вроде тоже самое, нет?
Насколько я понял master.poll() является асинхронной операцией, поэтому важно делать так, как написано в примерах. Асинхронность означает, что функция возвращает управление сразу, а не ожидает завершения какой-то операции.
может и асинхронна, не знаю, ок, попробую и строго по примерам. Спасибо
У меня вроде тоже самое, нет?
Ну и не обязательно делать 2 запроса. Вполне можно обойтись и одним, запрашивая 2 регистра, но также как в примерах.
Т.е. нужно дать задание и потом непрерывно "дергать" объект, проверяя не пришло ли чего.
идею понял, ща переделаю
Переделал, вот что вышло:
#include <ModbusRtu.h> #include <LiquidCrystal.h> #define TXEN 10 #define ID 10 uint16_t au16data[16]; uint8_t u8state; uint16_t flag = 1; union Data { struct REG { uint16_t LOWORD; uint16_t HIWORD; } reg; float fvalue; }; Data data; Modbus master(0,0,TXEN); modbus_t telegram; unsigned long u32wait; LiquidCrystal lcd(7, 6, 5, 4, 3, 2); void setup() { master.begin(19200); master.setTimeOut(1000); u32wait = millis() + 3000; u8state = 0; lcd.begin(16, 2); lcd.print("hello, world!"); } void loop() { switch( u8state ) { case 0: if (millis() > u32wait) u8state++; break; case 1: telegram.u8id = ID; telegram.u8fct = 4; telegram.u16RegAdd = 1000; telegram.u16CoilsNo = 2; telegram.au16reg = au16data; master.query(telegram); u8state++; break; case 2: master.poll(); if (master.getState() == COM_IDLE) { //data.reg.LOWORD = au16data[0]; //data.reg.HIWORD = au16data[1]; data.reg.HIWORD = 0x38a0; data.reg.LOWORD = 0x93b1; lcd.setCursor(0, 1); lcd.print(data.fvalue); u8state = 0; u32wait = millis() + 3000; } break; } }Проверил на установке - данные шлем и получаем! Ура!
Теперь беда с отображением полученных данных на экране. Для этого в 56 и 57 явно подставил значения и надеялся получить на экране что нить типа 0.00007656 или 7.656е-005 но дает 0.00
Вариант lcd.print(data.fvalue*100000); единственный для получения результата или можно без умножения?
Очень хотелось бы видеть на экране не только 2 знака после запятой
PS
Разобрался!