Arduino oled i modbus rtu

Masz problem, z którym nie możesz sobie poradzić? Pisz śmiało!
ODPOWIEDZ
cinek_14
Młodszy majsterkowicz
Posty: 1
Rejestracja: 29 maja 2019, 08:20

Arduino oled i modbus rtu

Post autor: cinek_14 » 29 maja 2019, 13:08

Witam, konstruuje moduł do tzw. inteligentnego domu moduł znajdzie się w puszce pod włącznikiem. Zadania jakie będzie realizował to:
- pomiar temperatury DS18b20,
- enkoder (będzie zrealizowany na przerwaniach),
- 8 wejść cyfrowych,
- wyświetlacz oled do wyświetlania parametrów (OLED 0,96' 128x64 na I2C - SSD1306).
Moduł będzie komunikował się z sercem domu mianowicie z Fatkiem, który będzie sterował wszystkimi urządzeniami w domu. Komunikacja pomiędzy fatkiem, a modułami będzie realizowana poprzez RS485 z MODBUS RTU.
Jestem na etapie pisania programu do modułu lecz trafiłem na problem. Problem polega na tym, że w pętli głównej programu mam obsługę modbus-a i oleda, który generuje znaczne opóźnienie wykonywanego programu. W jaki sposób mogę rozwiązać obsługę oleda, aby działała niezależnie od głównej pętli?

Kod: Zaznacz cały

#include <SimpleModbusSlave.h>
#include <OneWire.h>
#include <DS18B20.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

/*
   SimpleModbusSlaveV10 supports function 3, 6 & 16.
   function 3: READ_HOLDING_REGISTERS    **** this example uses this function [4-7]
   function 6: PRESET_SINGLE_REGISTER
   function 16: PRESET_MULTIPLE_REGISTERS **** this example uses this function [0-3]
*/

//konfiguracja modbus
#define TxEnablePin 8
#define   baud 57600   //9600
#define   SlaveID 1
#define   HOLDING_REGS_SIZE 220

//wejscia
#define SW1 A0
#define SW2 A1
#define SW3 A2
#define SW4 A3
#define SW5 9
#define SW6 10
#define SW7 5
#define SW8 6
#define NAPIECIE 7
#define ENC_L 2
#define ENC_R 3
#define ENC_BT 4
#define DS18B20_pin 13


//konfiguracja ds18b20
const byte ONEWIRE_PIN = DS18B20_pin;
OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);
byte address[8];
float temperatura;

unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array
unsigned int successful_requests;

//konf oleda
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


void setup()
{
  modbus_configure(&Serial, baud, SERIAL_8N2, SlaveID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);
  modbus_update_comms(baud, SERIAL_8N2, SlaveID);

  pinMode(SW1, INPUT_PULLUP); //Przycisk 1
  pinMode(SW2, INPUT_PULLUP); //Przycisk 2
  pinMode(SW3, INPUT_PULLUP); //Przycisk 3
  pinMode(SW4, INPUT_PULLUP); //Przycisk 4
  pinMode(SW5, INPUT_PULLUP); //Przycisk 5
  pinMode(SW6, INPUT_PULLUP); //Przycisk 6
  pinMode(SW7, INPUT_PULLUP); //Przycisk 7
  pinMode(SW8, INPUT_PULLUP); //Przycisk 8
  pinMode(NAPIECIE, INPUT); //pomiar napięcia  
  //pinMode(ENC_L, INPUT); //ENC L
  //pinMode(ENC_R, INPUT); //ENC P
  pinMode(ENC_BT, INPUT); //ENC BT
  
    onewire.reset_search();
  while(onewire.search(address))
  {
    if (address[0] != 0x28)
      continue;
  }
  sensors.begin(10);
  sensors.request(address);

  //oled
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();

}

void loop()
{ 
 
 modbus_update();
 
  //odczyt czujnika ds18b20
  if (sensors.available())
  {
    temperatura = sensors.readTemperature(address)*10;
    sensors.request(address);
  }
 
  if (digitalRead(SW1) == LOW) {holdingRegs[0] = 1;} else {holdingRegs[0] = 0;}
  if (digitalRead(SW2) == LOW) {holdingRegs[1] = 1;} else {holdingRegs[1] = 0;}
  if (digitalRead(SW3) == LOW) {holdingRegs[2] = 1;} else {holdingRegs[2] = 0;}
  if (digitalRead(SW4) == LOW) {holdingRegs[3] = 1;} else {holdingRegs[3] = 0;}
  if (digitalRead(SW5) == LOW) {holdingRegs[4] = 1;} else {holdingRegs[4] = 0;}
  if (digitalRead(SW6) == LOW) {holdingRegs[5] = 1;} else {holdingRegs[5] = 0;}
  if (digitalRead(SW7) == LOW) {holdingRegs[6] = 1;} else {holdingRegs[6] = 0;}
  if (digitalRead(SW8) == LOW) {holdingRegs[7] = 1;} else {holdingRegs[7] = 0;}
  
  holdingRegs[8] = temperatura; //wystawienie na rejestr 8 temperatury  

  holdingRegs[9] = (analogRead(NAPIECIE)*10) / 20; // pomiar napięcia zasilania 

  //enc bt
  if (digitalRead(ENC_BT) == LOW) {holdingRegs[11] = 1;} else {holdingRegs[11] = 0;}
  
  display.clearDisplay();

  display.setTextSize(2);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
  display.println(F("Hello, world!"));

  display.display();
}

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


ODPOWIEDZ

Strony partnerskie: