bkintz
I've located properly working C code to read the humidity and temp values from the AM2302, but my C coding skills has about 25 years of rust on it and I'm not able to translate it into the OpenPLC Code box where it functions. 

The code is the example located here: 
http://www.uugear.com/portfolio/read-dht1122-temperature-humidity-sensor-from-raspberry-pi/

only change is that my DHT_PIN is 7 vice 3. When compiled it reports data properly from the bash shell on the pi, so I know the libraries are there and both my hardware as well as my connection points to the GPIO are good.

Can someone assist?
Quote 0 0
NWT.Stuff
I think I have one of those in my bag of bits. I’ll give it a try next week sometime and get back to you.
Quote 0 0
bkintz
Awesome. That would be very much appreciated!
Quote 0 0
thiagoralves
I quickly check that code, it is heavily based on timings. It won’t ever work with OpenPLC unless it is placed on a separate thread. If you don’t, it will make OpenPLC scan time slow to a crawl. 
Quote 0 0
NWT.Stuff
blintz it would be useful to know the objective of your project ?
Why RPI ?
Why OpenPLC ?

For example if I wanted to log values to a database. I would:-
-use an arduino with Ethernet connectivity
-program in C language on Arduino IDE
-write values to database on required frequency.

if I wanted to control the temperature and humidity of a room I would
-still use arduino software to read values
-connect arduino to RPI with a USB cable
-use PID control in Open PLC
-configure arduino as slave device in OpenPLC.

The arduino is very well suited to this application and this is kind of mentioned at the bottom of the link that you posted.



Quote 0 0
bkintz
I'm building a ICS pen testing lab and want to have a setup with an HMI that can collecting point values from a variety of PLCs that I can manipulate with my attacks and I have a handful of pi boards on hand. If arduino is the path of least resistance, i can certainly explore that route.
Quote 0 0
thiagoralves
Definitely Arduino would be the easiest route. You can have the arduino reading your DHT sensors and sending the data over to the host (Raspberry Pi running OpenPLC) over Modbus. All you have to do is get the OpenPLC firmware for the Arduino and slightly modify it to add the DHT11 readings
Quote 0 0
bkintz
OK, I'll give that a go and see what happens
Quote 0 0
NWT.Stuff
I have attached the current project I am working on.  The kit on page 1 (python + mysql + flask) has been active for about 4 Years now without any hardware failures.  I still like to have the pi as my first level on the TCP/IP network as it makes it easy to make changes to the Arduino using Arduino IDE on the PI (As i can log in as a VNC Client from a PC).  But for Analogues in , pulses etc. and simplicity the Arduino works a treat.  Plenty of code and support around to.  I guess I'm saying the best solution is to use them together.  And OpenPLC will do that nicely too with the Slave Option.

I'll give the temp & Humidity sensor a run on my Arduino next week  ðŸ™‚
Quote 0 0
NWT.Stuff
OK Bkintz

I found a KY-015 in my bag of bits. Pretty sure the physical nature of the device will be similar.  I did a bit of googling and found these two projects.

https://www.tutorialspoint.com/arduino/arduino_humidity_sensor.htm

https://arduinomodules.info/ky-015-temperature-humidity-sensor-module/

I went with the 2nd one as it doesn't require the additional step of including a library.

Wiring.jpg 

Downloaded the Code to Arduino
ArduinDL.jpg 

Results in Serial Monitor

SerialMon.jpg 

Fairly happy as my room thermostat said 20.2 degC.  I also tried heating it up with my partners hairdryer.  Responded as exepected.

I think the next thing I will do is put a long wire on it an see what it says in the bathroom 🙂

Not sure of the best way now to get these values into the PLC register.  So hopefully someone on the forum can help with that.

Good Luck, Kevin 
Quote 0 0
bkintz
OK, I have the arduino nano hooked up to the DHT22 and was able to load firmware onto it that printed out the temp, humidity, & heat index to the serial monitor, so I know my wiring is good and that the sensor and the nano are functioning properly. Now to modify the openplc arduino firmware to populate those data points into registers. 

Below is what my code is looking like using the adafruit DHT library:

So as not to mess with the I/O ports connected to physical pins, I added an additional 3 input registers which I attempt to manually set to the values obtained from the DHT and set the nano up as a generic RTU device in openplc so I could add the 3 additional IRs.

I'm being thrown by the fact I'm getting floats from the DHT but the IRs are word values. Adds/mods to the stock nano openplc code are bolded:

#include <Arduino.h>
#include "Modbus.h"
#include "ModbusSerial.h"
#include <DHT.h>
#include <DHT_U.h>
// DHT setup info
#define DHTPIN 4 // what digital pin we're connected to
// Uncomment whatever type you're using!
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
//ModBus Port information
#define BAUD        115200
#define ID          0
#define TXPIN       -1
//Define the number of registers, inputs and coils to be created
#define NUM_DISCRETE_INPUTS      5
#define NUM_INPUT_REGISTERS     6
#define NUM_TOTAL_IRS            9
#define NUM_INPUT_REGISTERS     6
#define NUM_COILS               4
#define NUM_HOLDING_REGISTERS   3
//Create the I/O pin masks
uint8_t pinMask_DIN[] = {2, 3, 4, 5, 6};
uint8_t pinMask_AIN[] = {A0, A1, A2, A3, A4, A5};
uint8_t pinMask_DOUT[] = {7, 8, 12, 13};
uint8_t pinMask_AOUT[] = {9, 10, 11};
//Modbus Object
ModbusSerial modbus;
void configurePins()
{
    for (int i = 0; i < NUM_DISCRETE_INPUTS; i++)
    {
        pinMode(pinMask_DIN[i], INPUT);
    }
    
    for (int i = 0; i < NUM_INPUT_REGISTERS; i++)
    {
        pinMode(pinMask_AIN[i], INPUT);
    }
    
    for (int i = 0; i < NUM_COILS; i++)
    {
        pinMode(pinMask_DOUT[i], OUTPUT);
    }
    for (int i = 0; i < NUM_HOLDING_REGISTERS; i++)
    {
        pinMode(pinMask_AOUT[i], OUTPUT);
    }
}
void setup()
{
    //Setup board I/O
    configurePins();
     dht.begin();
     
    //Config Modbus Serial (port, speed, rs485 tx pin)
    modbus.config(&Serial, BAUD, TXPIN);
    
    //Set the Slave ID
    modbus.setSlaveId(ID); 
    
    //Add all modbus registers
    for (int i = 0; i < NUM_DISCRETE_INPUTS; ++i) 
    {
        modbus.addIsts(i);
    }
    for (int i = 0; i < NUM_TOTAL_IRS; ++i) 
    {
        modbus.addIreg(i);
    }
    for (int i = 0; i < NUM_COILS; ++i) 
    {
        modbus.addCoil(i);
    }
    for (int i = 0; i < NUM_HOLDING_REGISTERS; ++i) 
    {
        modbus.addHreg(i);
    }
}
void loop()
{
    //Run the main modbus task
    modbus.task();
    float h = dht.readHumidity();
   // Reading temperature or humidity takes about 250 milliseconds!
    float f = dht.readTemperature(true);
   // Read temperature as Fahrenheit (isFahrenheit = true)
    float hif = dht.computeHeatIndex(f, h);
    //compute heat index from temp and humidity
        modbus.Ireg(6,word(h)); 
        modbus.Ireg(7,word(f));
        modbus.Ireg(8,word(hif));        
     
    //Update modbus registers
    for (int i = 0; i < NUM_DISCRETE_INPUTS; ++i) 
    {
        modbus.Ists(i, digitalRead(pinMask_DIN[i]));
    }
    for (int i = 0; i < NUM_INPUT_REGISTERS; ++i) 
    {
        modbus.Ireg(i, (analogRead(pinMask_AIN[i]) * 64));
    }
    for (int i = 0; i < NUM_COILS; ++i) 
    {
        digitalWrite(pinMask_DOUT[i], modbus.Coil(i));
    }
    for (int i = 0; i < NUM_HOLDING_REGISTERS; ++i) 
    {
        analogWrite(pinMask_AOUT[i], (modbus.Hreg(i) / 256));
    }
}


thoughts?
Quote 0 0
thiagoralves
I don't have DHT sensors to test this, but it could work as long as you reduce the polling rate of your slave devices to something like 500ms or 1 second, otherwise you will get a lot of communication errors on OpenPLC since the Arduino will be busy in wait loops reading the DHT sensor (it takes 250ms for each reading, which is insane).

A more wiser idea would be to move the DHT reading commands to a separate timed function that is called from loop every 1 second or so. On the way it is coded now the DHT readings are called all the time, leaving basically no space left for the modbus task to run which is essencial for the slave device to work.

Also, I would make the float conversion differently. Something like this works better:
float h_float = dht.readHumidity();
h_float = h_float * 100; //keep 2 decimal digits
uint16_t h_int = (uint16_t)h_float; //keep only the integer part, which includes 2 decimal digits
Quote 1 0