ATtiny – Modbus met DHT sensor
Op deze pagina vind je een manier om ATTiny en een Max485 chip te gebruiken als modbus interface voor een DHT sensor.
Wat heb je nodig?
- Hardware
- ATTiny85 chip
- Max485 chip (tbv modbus)
- DHT11 + Weerstand 4.7K
Sluit de onderdelen aan volgens onderstaand schema:
Script met Simplemodbus, Softwareserial en SimpleDHT
Stap 1
Stel softwareserial in om niet pin 0 en 1 te gebruiken maar 4 en 3, omdat veel bibliotheken waaronder ook I2C master/slave voor de attiny altijd op pin 0 en 1 (SDA/SCL) toegewezen is.
Bewerk het bestand in de libraries folder: SimpleModbusSlaveSoftwareSerial\SimpleModbusSlaveSoftwareSerial.cpp
En vervang:
SoftwareSerial mySerial(0, 1);
in
SoftwareSerial mySerial(4, 3);
Zodende hebben we nu deze pinout:
ATTINY Pin 0 = DHT sensor
ATTINY Pin 2 = Max485 RX/TX Enable
ATTINY Pin 3 = Softwareserial TX (naar max485)
ATTINY Pin 4 = Softwareserial RX (naar max485)
Een baudrate van 9600/4800/2400/1200 zou ik aanbevelen, hieronder ID1, met baudrate 2400 8N1
Uitlezen met functie 3:
– Register 0 = Temperatuur
– Register 1 = Luchtvochtigheid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <SoftwareSerial.h> #include <SimpleModbusSlaveSoftwareSerial.h> #include <SimpleDHT.h> int pinDHT11 = 0; SimpleDHT11 dht11; //////////////// registers of your slave /////////////////// enum { // just add or remove registers and your good to go... // The first register starts at address 0 TEMP, HUM, TOTAL_ERRORS, // leave this one TOTAL_REGS_SIZE // total number of registers for function 3 and 16 share the same register array }; unsigned int holdingRegs[TOTAL_REGS_SIZE]; // function 3 and 16 register array //////////////////////////////////////////////////////////// void setup() { /* parameters(long baudrate, unsigned char ID, unsigned char transmit enable pin, unsigned int holding registers size) The transmit enable pin is used in half duplex communication to activate a MAX485 or similar to deactivate this mode use any value < 2 because 0 & 1 is reserved for Rx & Tx */ modbus_configure(9600, 1, 2, TOTAL_REGS_SIZE); } void loop() { // read without samples. byte temperature = 0; byte humidity = 0; int err = SimpleDHTErrSuccess; if ((err = dht11.read(pinDHT11, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) { holdingRegs[0] = 0; holdingRegs[1] = 0; return; } holdingRegs[0] = (int)temperature; holdingRegs[1] = (int)humidity; modbus_update(holdingRegs); } |
Voorbeeld met DHT22 sensor en tijdinterval
Uitlezen met functie 3:
– Register 0 = Temperatuur HEEL
– Register 1 = Temperatuur DECIMAAL
– Register 2 = Luchtvochtigheid HEEL
– Register 3 = Luchtvochtigheid DECIMAAL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#include <SoftwareSerial.h> #include <SimpleModbusSlaveSoftwareSerial.h> #include <SimpleDHT.h> int pinDHT22 = 0; float temperature = 0; float humidity = 0; unsigned long oudetijdsen = 0; int mivsen = 2000; // Interne meetinterval van de sensoren in ms. SimpleDHT22 dht22; //////////////// registers of your slave /////////////////// enum { // just add or remove registers and your good to go... // The first register starts at address 0 TEMP_HEEL, TEMP_DEC, HUM_HEEL, HUM_DEC, TOTAL_ERRORS, // leave this one TOTAL_REGS_SIZE // total number of registers for function 3 and 16 share the same register array }; unsigned int holdingRegs[TOTAL_REGS_SIZE]; // function 3 and 16 register array //////////////////////////////////////////////////////////// void setup() { /* parameters(long baudrate, unsigned char ID, unsigned char transmit enable pin, unsigned int holding registers size) The transmit enable pin is used in half duplex communication to activate a MAX485 or similar to deactivate this mode use any value < 2 because 0 & 1 is reserved for Rx & Tx */ modbus_configure(9600, 1, 2, TOTAL_REGS_SIZE); } void loop() { unsigned long tijdnu = millis(); // Lees sensor op meetinterval. if(tijdnu - oudetijdsen > mivsen) { oudetijdsen = tijdnu; writedatasen(); } modbus_update(holdingRegs); } void writedatasen() { holdingRegs[0] = 0; holdingRegs[1] = 0; holdingRegs[2] = 0; holdingRegs[3] = 0; // read without samples. int err = SimpleDHTErrSuccess; if ((err = dht22.read2(pinDHT22, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) { return; } // LEESFOUT int tempheel = (float)temperature; int tempdecimaal = ((float)temperature - tempheel) * 100; holdingRegs[0] = tempheel; holdingRegs[1] = tempdecimaal; int humheel = (float)humidity; int humdecimaal = ((float)humidity - humheel) * 100; holdingRegs[2] = humheel; holdingRegs[3] = humdecimaal; } |