Информация от DS18B20 по RS485
- Войдите на сайт для отправки комментариев
Вс, 31/05/2020 - 23:26
Добрый день. Подскажите, пожалуйста, как организовать передачу/прием информации от датчиков температуры по RS485 так чтобы можно было обрабатывать каждый датчик независимо от другого? И как передать float по rs485?
Железо выглядит так:
- Передатчик. Нано, на ней три датчика ds18b20.
- Приемник. Уно, 4 ds18b20 на OneWire и прием по 485.
//Передатчик #include <SoftwareSerial.h> #include <SPI.h> #include <OneWire.h> #include <DallasTemperature.h> SoftwareSerial RS485Serial (9,10); const float PIN_DIR = 3; OneWire ds(2); DallasTemperature sensors(&ds); //Создаем объект sensors, подключенный по OneWire DeviceAddress temp1DeviceAddress; //переменная для хранения адреса датчика DeviceAddress temp2DeviceAddress; //второй информационный датчик //DeviceAddress temp3DeviceAddress; //переменная для хранения адреса датчика float temp[2]; void setup() { pinMode (PIN_DIR, OUTPUT); digitalWrite(PIN_DIR,HIGH); Serial.begin(9600); sensors.begin(); RS485Serial.begin(9600); } void loop() { //Запуск процедуры измерения температуры sensors.setWaitForConversion(false); sensors.requestTemperatures(); sensors.setWaitForConversion(true); delay(750); //Считывание значения температуры sensors.getAddress(temp1DeviceAddress, 0); temp[0] = sensors.getTempC(temp1DeviceAddress); Serial.print("Kabel 1 = "); Serial.print(temp[0]); Serial.println("C"); RS485Serial.write(temp[0]); delay(750); sensors.getAddress(temp2DeviceAddress, 1); temp[1] = sensors.getTempC(temp2DeviceAddress); Serial.print("Kabel 2 = "); Serial.print(temp[1]); Serial.println("C"); RS485Serial.write(temp[1]); //Приемник #include <SPI.h> #include <OneWire.h> #include <DallasTemperature.h> #include <SoftwareSerial.h> RF24 radio(10, 9); // CE, CSN OneWire ds(2); SoftwareSerial RS485Serial (6,7); const float PIN_DIR = 4; DallasTemperature sensors(&ds); //Создаем объект sensors, подключенный по OneWire DallasTemperature sensors_p(&ds_p); //Создаем переменные для работы с термометром DeviceAddress temp1DeviceAddress; //переменная для хранения адреса датчика DeviceAddress temp2DeviceAddress; //второй информационный датчик DeviceAddress temp3DeviceAddress; //переменная для хранения адреса датчика DeviceAddress temp4DeviceAddress; DeviceAddress temp5DeviceAddress; //второй информационный датчик DeviceAddress temp6DeviceAddress; //переменная для хранения адреса датчика DeviceAddress temp7DeviceAddress; float temp; float temp_p; void setup() { pinMode (PIN_DIR, OUTPUT); digitalWrite(PIN_DIR,LOW); RS485Serial.begin(9600); Serial.begin(9600); sensors.begin(); sensors_p.begin(); delay(2); } void loop() { // Запуск процедуры измерения температуры sensors.setWaitForConversion(false); sensors.requestTemperatures(); sensors.setWaitForConversion(true); delay(750); sensors_p.setWaitForConversion(false); sensors_p.requestTemperatures(); sensors_p.setWaitForConversion(true); //Считывание значения температуры sensors.getAddress(temp1DeviceAddress, 0); temp[0] = sensors.getTempC(temp1DeviceAddress); Serial.print("Kabel 1 = "); Serial.print(temp[0]); Serial.println("C"); delay(750); sensors.getAddress(temp2DeviceAddress, 1); temp[1] = sensors.getTempC(temp2DeviceAddress); Serial.print("Kabel 2 = "); Serial.print(temp[1]); Serial.println("C"); delay(750); sensors.getAddress(temp3DeviceAddress, 2); temp[2] = sensors.getTempC(temp3DeviceAddress); Serial.print("Kabel 3 = "); Serial.print(temp[2]); Serial.println("C"); delay(750); sensors.getAddress(temp4DeviceAddress, 3); temp[3] = sensors.getTempC(temp4DeviceAddress); Serial.print("Kabel 4 = "); Serial.print(temp[3]); Serial.println("C"); delay(750); if (RS485Serial.available() > 0) temp = RS485Serial.read(); Serial.write(RS485Serial.read()); Serial.println (temp); delay (100); }
Тип флоат на ардуино - это 4 байта. А вы в коде передаете только один байт, поэтому ничего хорошего не выходит.Чтобы передать флоат по Сериал или по RS485 - нужно сначала разбить флоат на 4 байта, потом передать эти байты - а потом в приемнике обратно собрать из 4х байтов флоат.
А чтобы передавать данные двух датчиков - нужно передавать не только температуру. но и номер датчика.
Но это еще не все. Понимаете, правильно передавать данные между ардуинами - это немного больше чем просто пихать байты в линию со стороны передачтчика и ждать что они придут на приемник :) На самом деле тут нужно позаботится о том, что бы обе ардуины понимали, когда начинается передача, сколько в ней байт, когда она закончена, а так же умели проверять правильность принятых данных. Все это обеспечивается так называемым протоколом - правилами передачи, которые вы либо должны описать в программе сами. либо использовать готовый, например Модбас
Тип флоат на ардуино - это 4 байта. А вы в коде передаете только один байт, поэтому ничего хорошего не выходит.Чтобы передать флоат по Сериал или по RS485 - нужно сначала разбить флоат на 4 байта, потом передать эти байты - а потом в приемнике обратно собрать из 4х байтов флоат.
Попробовал разбить флоат так:
А собрать так:
ничего не получилось. Пришли какие-то непонятные символы. Подскажите, хоть в какую сторону смотреть, может есть что почитать доступным языком про int в float?
Выкусил из рабочей прошивки. Возможно, что-то упустил, но принцип должен быть понятен. Каждая температура передается в двух 16-битных регистрах modbus: