• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
DS18S20 I RS485
#1
Witam.
Czy ktos moze doradzic z kodem. Sprawa w skrocie wyglada tak: Pierwsze arduino podlaczone dwa sensory temperatury RS18S20 oraz LCD 2004 ktory wyswietla temperatury z obu sensorow oraz modul RS485 ktory wysyla temperatury z obu sensorow np 19.64 stC i 22.36 stC, monitor poru pokazuje obie temperatury na ekranie PC. Drugie Arduino z wyswietlaczem LCD 2004 i RS485 i tak: monitor portu szeregowego odbiera tylko liczby czlkowite bez liczb po przecinku. I tutaj pytanie: Jak sformulowac kod, aby odebrac dane z liczbami po przecinku oraz wyswietlic obie temperatury na LCD. Jesli ktos moze pomoc i potrzebuje kod master i slave to moge wyslac. Niestety w internecie nie znalazlem nic co moglo by pomoc.
Z gory dziekuje.
 
Odpowiedź
#2
Najprostsze wykorzystanie RS485 niczym nie różni się od wysyłania komunikatów po UART między dwoma Arduino, a do tego to przykładów już znajdziesz na pęczki.
Możesz mieć co prawda na czas wysyłania ustawienie kierunku linii RS485, ale są też takie moduły, które ustawiają kierunek automatycznie.
Kod można wkleić w post, im więcej osób go zobaczy, tym większa szansa, że ktoś zauważy na którym etapie gubisz dane.
 
Odpowiedź
#3
Jeżeli wyświetlanie na drugim Arduino ma być jedynym, do czego wykorzystujesz dane o temperaturach to nie musisz ich w żaden sposób konwertować. W nadającej maszynie za pomocą sprintf() składasz to, co masz wysłać i co ma pokazać drugie Arduino, a na drugim tylko wrzucasz wszystko, co odebrałeś z RS485 na ekran.
 
Odpowiedź
#4
Oto moje skatche...

Dla MASTER:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <OneWire.h>
#include <DallasTemperature.h>
//=====================================================================================================================================
#include "Arduino.h"
// Library to allow a Serial port on arbitrary pins
#include <SoftwareSerial.h>
// These are the pins we'll be talking to the RS485 device on
#define RS485rx 2 // RS485 Receive pin
#define RS485Tx 3 // RS485 Transmit pin
#define RS485Transmit HIGH
#define RS485Receive LOW
#define baudRate 115200
SoftwareSerial RS485(RS485rx, RS485Tx);
int buttonState = 0;

//=====================================================================================================================================

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 4

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Addresses of 3 DS18B20s
uint8_t sensor1[8] = { 0xX, 0xX, 0xX, 0xX, 0xX, 0xX, 0xX, 0xX };
uint8_t sensor2[8] = { 0xX, 0xX, 0xX, 0xX, 0xX, 0xX, 0xX, 0xX };
uint8_t sensor3[8] = { 0xX, 0xX, 0xX, 0xX, 0xX, 0xX, 0xX, 0xX };
float tempC1 = 0;
float tempC2 = 0;
float tempC3 = 0;
float times =10000;


void setup()
{
lcd.init();
lcd.begin(20, 4);
lcd.backlight();
Wire.begin();
sensors.begin();
lcd.setCursor(4, 0);
lcd.print("TEMPERATURA");
Serial.begin(9600);  
sensors.setResolution(sensor1, 12);
sensors.setResolution(sensor2, 12);
sensors.setResolution(sensor3, 12);

 pinMode(5, OUTPUT);
 pinMode(A0, INPUT);
 
 sensors.requestTemperatures();
 float tempC1 = sensors.getTempC(sensor1);
 float tempC2 = sensors.getTempC(sensor2);
 float tempC3 = sensors.getTempC(sensor3);
 lcd.setCursor(1, 1);
  lcd.print("Wewnatrz: ");
  lcd.setCursor(11, 1);
  lcd.print(tempC1);
  lcd.setCursor(1, 2);
  lcd.print("Zewnatrz: ");
  lcd.setCursor(11, 2);
  lcd.print(tempC2);
  lcd.setCursor(1, 3);
  lcd.print("Sensor 3: ");
  lcd.setCursor(11, 3);
  lcd.print(tempC3);

 

//=====================================================================================================================================
 RS485.begin(baudRate);
//=====================================================================================================================================

}

void loop()
{
 
  buttonState = analogRead(A0);
  if (buttonState >= 1000)
  {
    digitalWrite(5, HIGH);
  }
  if (buttonState <= 1000)
  {
    digitalWrite(5, LOW);
  }
 
static float count = 0;
count++; if (count==times)
{
sensors.requestTemperatures();
float tempC1 = sensors.getTempC(sensor1);
float tempC2 = sensors.getTempC(sensor2);
float tempC3 = sensors.getTempC(sensor3);
float rxtempC1;
float rxtempC2;
float rxtempC3;

  lcd.setCursor(11, 1);
  lcd.print(tempC1);
  lcd.setCursor(11, 2);
  lcd.print(tempC2);
  lcd.setCursor(11, 3);
  lcd.print(tempC3);

//=====================================================================================================================================

Serial.print("Sending:");Serial.println(sensors.getTempC(sensor3));
 RS485.write(sensors.getTempC(sensor3));
 delay(1);

 if (RS485.available())
 {
rxtempC3 = RS485.read();
 // Display it on the Serial Monitor as a char (not an integer value)
 Serial.print(" Got back:"); Serial.println(rxtempC3);
 }
 count =0;
}
//=====================================================================================================================================
}



Oraz SLAVE:


#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
int tempC1= 0;
int tempC2= 0;
int tempC3= 0;
//=====================================================================================================================================
#include "Arduino.h"
// Library to allow a Serial port on arbitrary pins
#include <SoftwareSerial.h>
// These are the pins we'll be talking to the RS485 device on
#define RS485rx 2 // RS485 Receive pin
#define RS485Tx 3 // RS485 Transmit pin
#define RS485Transmit HIGH
#define RS485Receive LOW
#define baudRate 115200
// Define the RS485 object
SoftwareSerial RS485(RS485rx, RS485Tx);
float rxtempC1;
float rxtempC2;
float rxtempC3;
//=====================================================================================================================================

void setup()
{
lcd.init();
lcd.begin(20, 2);
lcd.backlight();
Wire.begin();
Serial.begin(9600);  


//=====================================================================================================================================
RS485.begin(baudRate);
//=====================================================================================================================================

}

void loop()
{
//=====================================================================================================================================
// Is there something on the serial pin?
 if (RS485.available())
 {
 float rxtempC3 = RS485.read();
 Serial.print("Received:");Serial.println(rxtempC3);
 lcd.setCursor(1, 0);
  lcd.print(rxtempC3);
  lcd.print("   ");
 delay(10);
 // Send back a modified value
 RS485.write(rxtempC3);
 }
//=====================================================================================================================================
}



Monitor portu dla MASTER:
Sending:19.69


Got back:19.00


Sending:19.69


Got back:19.00


Sending:19.69

Got back:19.00

Monitur portu dla SLAVE:
Received:19.00


Received:19.00


Received:19.00


Received:19.00

Received:19.00
 
Odpowiedź
#5
RS485.write(sensors.getTempC(sensor3));
nie napisałeś, że chcesz wysłać jako floata, to wysłał int'a. W AVR/C czy C++ jest domyślnie do wszystkiego int, liczba całkowita, hasło dnia "promocja do integer".
Na serial drukujesz float tempC1 to on wie, że to float.
Poza tym domyślnie DS działa tak, że jak zapytasz o temperaturę to on dopiero wtedy pyta jaka jest, termometr zaczyna pomiar, to trwa 750ms, wysyła i masz. Jak w jednym loop pytasz o 3, a potem znowu, i jeszcze wysyłasz na LCD, serial, RS485 to taki loop trwa kilka sekund, a powinien kilka us.
Zrób sobie zmienną globalną float na temperatury i RAZ odczytaną temperaturę wyślij na LCD, serial i do SLAVE.
Poza tym włącz tryb asynchroniczny dla DS, sam dbaj o to by zlecać pomiar i go odczytywać w odpowiednim czasie, np. na przykład zleć pomiar w SETUP, poczekaj 1s, wejdź do loop i tu już wywal wszystkie DELAY. Zacznij mierzyć sekundy w millis, gdy jest nowa sekunda odczytaj temperatury i zleć nowy pomiar.
W kolejnej sekundzie odczytasz pomiar zlecony w poprzedniej. Cały loop skraca się do czasu transmisji z czujnikami, czyli około 20ms na odczyt x3 i raz 20ms na zlecenie pomiarów do wszystkich. Ale to jest tylko ten 1 loop gdzie jest nowa sekunda, wszystkie inne loop w tej sekundzie wykonają się w kilka us. Chcesz zauważyć wciśnięcie jakiegoś przycisku, zmianę stanu pinu - voila, teraz możesz.
Oczywiście transmisji na UART/LCD czy RS485 też nie robisz w każdym loop, tylko co wybrany okres czasu, np. gdy jest nowy odczyt temp. Niestety to będzie ten sam loop, ale możesz tak ułożyć kod, że będzie kolejny, czyli najpierw się sprawdza czy wysłać temp bo jest nowy odczyt, a dopiero potem sprawdzasz czy odczytać.
Potem można to 80ms w jednym loop dla DS również rozbić tak, by nie robić w jednym loop wszystkich czterech transmisji. Można ustawić jakąś zmienną, że jest nowa sekunda, zrobić blok programu gdzie to odblokowuje wejście, przy pierwszym odczytać 1 czujnik, przy drugim trzeci, itd, zlecić pomiar, potem wysłać na LCD, potem wysłać na UART, potem wysłać na RS, zablokować wejście w ten blok ustawiając "jakąś zmienną=0" i znowu wejdziesz tu gdy nowa sekunda ustawi ją na 1.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości