Modbus RTU и отрицательные числа

mutis
Offline
Зарегистрирован: 24.09.2015

Здраствуите,
Выход нагрузки серво усилителя +- 0,5VDC.Через делитель подключил к  A0.Применив ''map'' настроил на ноль.В ''Serial.print''  всё отлично.Но мние нужен Modbus.И тут засада - от 0 в + всё правильно,а в - начинает с 65535.В нете накопал что 8 bit  Ардуины(255) и 16 bit Modbus(65535) надо как то  дополнительно объединить.А вот как ,ненашол.Может кто то решал уже такую задачу?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

скетч публикуй, если не желаешь получить хрустальным шаром в лоб.

mutis
Offline
Зарегистрирован: 24.09.2015

#include <ModbusRtu.h>
#define ID   1

Modbus slave(ID, 0, 0); // this is slave ID and RS-232 or USB-FTDI
boolean led;
int8_t state = 0;
unsigned long tempus;

// data array for modbus network sharing
uint16_t au16data[9];

void setup() {
  
  slave.begin( 19200 );
  tempus = millis() + 100;
  digitalWrite(13, HIGH );

}

void loop() {
  
  state = slave.poll( au16data, 9 );

  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );

  // link the Arduino pins to the Modbus array
  io_poll();
} 

void io_poll() {
  
  int val = analogRead(A0);//серво аналог 
  val = map(val, 248, 1023,0, 255); //ставлю в 0
    
  au16data[4] = val ;//выжод в модбус НЕПРАВИЛЬНЫЙ
  
 // Serial.print(val); // результат работы алгоритма правильный
 // Serial.println();

  // diagnose communication
  au16data[6] = slave.getInCnt();
  au16data[7] = slave.getOutCnt();
  au16data[8] = slave.getErrCnt();
}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

ок.

а, так Serial.print(unsigned int(val)); // правильный результат алхоритма?

mutis
Offline
Зарегистрирован: 24.09.2015
41  

 

mutis
Offline
Зарегистрирован: 24.09.2015

нет,

от 0 в + = правильно

от 0 в - = начинает от 65535

a Modbus без изменений

X-Dron
Offline
Зарегистрирован: 24.01.2015

И в чем проблема? 65535 это и есть "-1"

В Modbus-мастере настройте, чтобы полученное значение регистра интерпретировалось не как uint16, а как sint16.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

mutis пишет:

нет

так, не тупи тогда, вычитая из unsigned int

mutis
Offline
Зарегистрирован: 24.09.2015

Клапауций 112 пишет:

mutis пишет:

нет

так, не тупи тогда, вычитая из unsigned int

Можно по-подробнее?

А про Modbus я знаю только это:

http://www.homanndesigns.com/pdfs/Using_Modbus_with_Mach3.pdf

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

mutis пишет:

Клапауций 112 пишет:

mutis пишет:

нет

так, не тупи тогда, вычитая из unsigned int

Можно по-подробнее?

unsigned int

mutis
Offline
Зарегистрирован: 24.09.2015

Я уже писал,что (unsigned int  val;) в сериале от 0 в + правильно,а в - начинает от 65535,
а в Modbus тоже идентично.

Condensator
Offline
Зарегистрирован: 02.06.2017

mutis пишет:
Я уже писал,что (unsigned int  val;) в сериале от 0 в + правильно,а в - начинает от 65535

Лучше бы не писал, а читал про дополнительный код  и представление отрицательного числа.

X-Dron
Offline
Зарегистрирован: 24.01.2015

Скажи мне в чем разница этих записей?

#FFFF

1111 1111 1111 1111 1111

-1

65535

Ни в чем!!! В шестнадцати-битной ячейке это одно и тоже значение. Разница только в интерпретации.

Modbus не является объектно-ориентированным протоколом. Он имеет дело только с регистрами, а что в этих регистрах находится ему без разницы. Все зависит он интерпретации. В двух регистрах может быть короткий Float, а может быть вообще 8 char.

Поэтому возьми модбас-тестер (модбас-мастер), который может отображать значения полученных регистров в нужное представление (тебе нужен signed int). 

mutis
Offline
Зарегистрирован: 24.09.2015

дополнительный код  и представление отрицательного числа.

Кажетса,я больше писатель,чем читатель.Меняя типы (int,signed int ,unsigned int) в сериале  разное отображение,а в модбусе - без разницы.Я не настолько силён ,так что мние нужен  исполнитель.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

mutis пишет:

Кажетса,я больше писатель,чем читатель.Меняя типы (int,signed int ,unsigned int) в сериале  разное отображение,а в модбусе - без разницы.Я не настолько силён ,так что мние нужен  исполнитель.

ок.

у тебя есть возможность программно сдвинуть шкалу значений переменной val с 0 до 32767 ?

те.:

32767 - это 0.

32766 - это -1

32768 - это  1

или это #6

 

nik182
Offline
Зарегистрирован: 04.05.2015

Пока до топикстартера не дойдет, что нет отрицательных,дробных и прочих чисел, есть только нолики и единички и наше представление о том, как эти нолики и единички интерпретировать, ничего объяснить не получится.

В модбас упаковываются нолики и единички в виде шестнадциразрядных групп. каждая группа имеет номер. Для простоты имеет описание uint_16. Как туда упаковать числа решает каждый сам. Главное потом восстановить - распаковать правильно.    

mutis
Offline
Зарегистрирован: 24.09.2015

В 1 посту писал,что ардуино 8 ,а модбус 16 бит .Тут биты надо сравнивать,а вот как?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

mutis пишет:

В 1 посту писал,что ардуино 8 ,а модбус 16 бит .

хуйню писал.

mutis
Offline
Зарегистрирован: 24.09.2015

Особая благодарность «Condensator» за наводку #11.Некоторым советою ещё раз послушать « В Питере - пить» Решение в 39-40 строках.


#include <ModbusRtu.h>
#define ID   1

Modbus slave(ID, 0, 0); // this is slave ID and RS-232 or USB-FTDI
boolean led;
int8_t state = 0;
unsigned long tempus;

// data array for modbus network sharing
uint16_t au16data[9];

void setup() {
  
  slave.begin( 19200 );
  tempus = millis() + 100;
  digitalWrite(13, HIGH );
 }

void loop() {

 state = slave.poll( au16data, 9 );

  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );

  // link the Arduino pins to the Modbus array
  io_poll();
 } 
void io_poll() {
  int a ;
  unsigned int val;

  val = analogRead(A0);//серво аналог 
  val = map(val, 248, 1023,0, 255); //ставлю в 0
  a=val;
if (a < 0)
  a = (~a)|0;
  au16data[4] = a ;//выжод в модбус 
 
/*
  Serial.print(a); // результат работы алгоритма правильный
  Serial.println();
*/
  // diagnose communication
  au16data[6] = slave.getInCnt();
  au16data[7] = slave.getOutCnt();
  au16data[8] = slave.getErrCnt();
}

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

a=(~a)|0;

Это прям в копилку маразмов.

mutis
Offline
Зарегистрирован: 24.09.2015

DetSimen пишет:

a=(~a)|0;

Это прям в копилку маразмов.

Нет завален тупыми застольными дебатами.

А палочку с 0 пока оставил ,это как бы оффсет .Скеч работает.Хоть пояснили,в чём маразм?

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Аптмуш операция ИЛИ 0 бессмысленна.

mutis
Offline
Зарегистрирован: 24.09.2015

Ну да,так как начало числа передвинуть ненужно, хватило и 

  a=~a;

nik182
Offline
Зарегистрирован: 04.05.2015

Скажите, а в какой момент число становится отрицательным? Ну чисто теоретически? Результат АЦП пололожительный. map тоже положительный.  

mutis
Offline
Зарегистрирован: 24.09.2015

Чисто практически, прочитаете с самого начала.Я зацепилса за выход сервы...и покатилось...

nik182
Offline
Зарегистрирован: 04.05.2015

 Я помню про серву. Мой вопрос про программу в посте #18. В строках 36-38 отрицательного числа быть не может.   Зачем в строке 38 переменная val - двухбайтовая беззнаковая, в точности соответствующая регистру модбас - копируется в двухбайтовое знаковое? Хочу заметить,что после MAP значение будет укладываться в один байт и никогда не превратиться в отрицательное. Так где число станет отрицательным?   

mutis
Offline
Зарегистрирован: 24.09.2015

Я не имею опoрных знаний программирования. прочитал инфо из #11 ,сделал   copy-paste ,и заработало.Работает и так:
     int val;  
    if (val < 0)
    val = ~val;
Юридически слово отрицательный надо менять на обратный или перевёрнутый.

Court
Offline
Зарегистрирован: 08.07.2017

mutis пишет:

#include <ModbusRtu.h>
#define ID   1

Modbus slave(ID, 0, 0); // this is slave ID and RS-232 or USB-FTDI
boolean led;
int8_t state = 0;
unsigned long tempus;

// data array for modbus network sharing
uint16_t au16data[9];

void setup() {
  
  slave.begin( 19200 );
  tempus = millis() + 100;
  digitalWrite(13, HIGH );

}

void loop() {
  
  state = slave.poll( au16data, 9 );

  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );

  // link the Arduino pins to the Modbus array
  io_poll();
} 

void io_poll() {
  
  int val = analogRead(A0);//серво аналог 
  val = map(val, 248, 1023,0, 255); //ставлю в 0
    
  au16data[4] = val ;//выжод в модбус НЕПРАВИЛЬНЫЙ
  
 // Serial.print(val); // результат работы алгоритма правильный
 // Serial.println();

  // diagnose communication
  au16data[6] = slave.getInCnt();
  au16data[7] = slave.getOutCnt();
  au16data[8] = slave.getErrCnt();
}

 

Поделитесь пожалуйста ссылкой на github,  где лежит библиотека  ModbusRTU.h или  Modbusrtu .  Нужна для работы в режимах Master и Slave

nik182
Offline
Зарегистрирован: 04.05.2015