Download - EasyEDA

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts

Mains electricity wikipedia, lookup

Buck converter wikipedia, lookup

Switched-mode power supply wikipedia, lookup

Opto-isolator wikipedia, lookup

Resistive opto-isolator wikipedia, lookup

Pulse-width modulation wikipedia, lookup

Ohm's law wikipedia, lookup

Immunity-aware programming wikipedia, lookup

Power over Ethernet wikipedia, lookup

Control system wikipedia, lookup

Analog-to-digital converter wikipedia, lookup

Protective relay wikipedia, lookup

Resistor wikipedia, lookup

Relay wikipedia, lookup

Transcript
Rpi Temperature I/O Board Technical Manual
Prepred for Customer: David @ Wine Technologies Marlborough (www.vinwizard.us)
Licence: GPL <Or Whatever David Finally Decides>
Based on Hardware Rev 5: 2 Aug 2016
System overview
Sensors
The board is intended to accurately control the temperatures of 4 wine tanks using PT100 temperature probes
and actuating either a heat relay (if tank too cold) or a cool relay if tank to hot. The control program to do
this is run on a Raspberry Pi (R2 or R3) which the board will house and provide power and control.
The board connects to 4 external 3-wire PT100 temperature sensors. Each sensor is connected through a low
resistance analog multiplexer and polled every few seconds and the resistance of the selected PT100 (see
table) is converted to a voltage by passing a constant current though it of about 1mA (programable). The
voltage is conditioned to remove cable resistance and noise and then passed through a low pass filter (which
has a 3dB cut-off at 15Hz) and amplified and sent to the input of a 12 bit ADC. Internally two channels of an
input multiplexer are connected to calibration resistors so 6 channels are shown
Temperature
PT100 resistance (ohms)
Note
-12
95.30
* Lo Calibration Resistor (95.3 is a standard resistor value)
-10
96.09
0
100.00
10
103.90
20
107.79
30
111.67
40
115.54
50
119.40
60
123.24
62
120.01
* Hi Calibration Resistor (120 is a standard resistor value)
Note the hardware conditioning circuit and firmware are optimised for a temperature range of -12 to +62
DegC, small changes to the final amplifier gain and/or constant current and firmaware would be required to
change that range.
The calibration resistors are connected via the mux to the same conditioning circuit this means we can
connect known resistances and calibrate the output of the ADC to some degree of accuracy automatically.
There will be a small error depending upon how constant the analog multiplexers resistance matching value
is. The analog multiplexor has a maximum error of 0.2ohm which corresponds to about 0.4 DegC so this is
the maximum accuracy of the circuit without external calibration. Having calibration resistors means we can
find the temperature in software simply by taking the two know end points and approximating the PT100
sensor voltage on to this chart without any issues of drift etc.
Output Relays
Outputs from the board are from 8 x SPST Relays (Omron G5NB-1A-E) these are set in two banks of 4
relays with a common connection. Each relay is connected through a CPU output pin and can be individually
turned on or off . Due to PCB size constraints and proximity of tracks and relays to board edge the relays
outputs should be restricted to 24V@3A if used in the prescribed aluminium enclosure.
Power Supply and Controller
The board is controlled by a PIC16F1782 microcontroller, the microcontroller has its own 3.3V regultated
supply and consumes <10mA during normal operation. The 3.3V is provided by a 78L33 LDO connected
directly to the 24V supply through a 1K limiting resistor. It does not go through the polyfuse.
The Raspberry Pi is powered through its GPIO header from a 5V switched mode supply. The 5V supply is
fused on the input via a 1.5A polyfuse during normal operation the Rpi consumes under 100mA from this
supply. The LM2576-5 can supply up to 3A. Additional filtering of the 5V is provided by the 22uF inductor
and 220uF capacitor.
The system expects to be powered from an industrial 24V DC supply and will draw around 100-120mA
during normal operation. The Rpi may draw more transient current during heavy CPU load so the 24V
supply should be rated to 1A minimum.
The microcontroller does the following functions:
1. Selects the correct analog multiplexer channel and proceses the corrected and amplified analog
voltage from the PT100 or calibration resistor through its ADC converting to temperatures as
required.
2. Controls the enable pin to the LM2576 regulator to turn the RPi on and off.
3. Sends a power down signal to the Raspberry Pi 10 seconds before power down
4. Controls the 8 relays
5. Emulates an I2C slave for the Rpi so the Rpi can read temperatures and control relays.
6. Provides control of a buzzer alarm and two diagnotic LEDs
Raspberry Pi
The Raspberry Pi is connected to the board through its 40 pin GPIO header, this means it is restricted to the
Model 2 and model 3 boards, the model 1 board had a smaller header and is incompatable.
When 24V power is supplied to the board the microcontroller initialises and within 1 second turns on the 5V
for the Rpi so it can boot. All the relays are turned off and the microcontroller begins polling the PT100
channels and storing the ADC readings and temperatures.
The board looks to the Rpi like an I2C slave with a fixed address of 0x05
I2C Register Definitions
The board provides 40 x 8 bit addresses to the Rpi which control its operation, all can be read and written to
without causing error, though writing to read-only registers will be ignored and overwritten with the correct
values by the slave on the next pass. Addresses above 40 will not return a value to the RPi
(Name of register as defined in C Code is in red text to assist reading with source code)
0
MODE Read/Write (Default 0x00)
Bits 0 = Temperature Output mode:
0
1
Register is raw ADC value (Default) You have to do calculations yourself in the Rpi.
Register is temperature in MLP format:
ie Temp (DegC) = (Value/20) - 40 (eg 800 = 0.0DegC, 1234 = 21.7DegC)
Bits 2:3 = RPi Watchdog timer mode:
00
01
10
Off. RPi will never power cycle (Default)
For debugging only. first thing your RPi program should do is set this!
RPi will power cycle/reset if I2C Comms not received within 4 minutes
RPi will power cycle/reset if I2C Comms not received within 16 minutes
Bits 4:5 = Continuous fail mode:
00
01
10
RPi will power-off/reset upto 4 times then power on Rpi and sound alarm (Default)
RPi will power-off/reset upto 8 times then power on Rpi and sound alarm
RPi will power-off/reset upto 16 times then power on Rpi and sound alarm
Note each power off will be 4 seconds longer than the last as more failures occur, eg 1st failure will
be 4 seconds, second will be 8 seconds, 12, 16 .. up to a minute
Bits 6:7 (Reserved)
Regs 1+2
Regs 3+4
Regs 5+6
Regs 7+8
Regs 9+10
Regs 11+12
Regs 13+14
Regs 15+16
16-bit pt100 temperature sensors #1
16-bit pt100 temperature sensors #2
16-bit pt100 temperature sensors #3
16-bit pt100 temperature sensors #4
16-bit ADC Output Lo Calibration Resistor 95.3 ohm (-12DegC)
16-bit ADC Output Hi Calibration Resistor 120 ohm (62DegC)
16-bit ADC Output Lo Calibration Resistor 95.3 ohm (-12DegC)
16-bit ADC Output Hi Calibration Resistor 120 ohm (62DegC)
mux is an 8:1 analog mux channels 5 and 7 are connected together as are 6 and 8
Regs 13-16
(Reserved)
Regs 17+18
ADC reading for the 16-bit internal PIC16 temperature sensor.
Note this sensor is NOT a PT100 so see data sheet for how to work out temperature if
required.
Regs 19+20
ADC reading for the DAC output voltage reading see data sheet for info if required.
Reg 21
Reg 22
Reg 23
RLA1 Relay 1
RLA2 Relay 2
RLA3 Relay 3
0 = Relay Off, >0 = Relay On
0 = Relay Off, >0 = Relay On
0 = Relay Off, >0 = Relay On
Reg 24
Reg 25
Reg 26
Reg 27
Reg 28
RLA4
RLA5
RLA6
RLA7
RLA8
Relay 4
Relay 5
Relay 6
Relay 7
Relay 8
Regs 29-36
(Reserved)
Reg 37
Reg 38
Reg 39
UPTIMEL
UPTIMEH
STATUS
0 = Relay Off, >0 = Relay On
0 = Relay Off, >0 = Relay On
0 = Relay Off, >0 = Relay On
0 = Relay Off, >0 = Relay On
0 = Relay Off, >0 = Relay On
Uptime in hours (low byte)
Uptime in hours (High byte)
Status Register. Bit 0: 1=ready, 0=not ready
None of the above registers will retain there values across a power cycle of the 24V but will retain there
values if the Rpi is powered off and on by the watchdog timer. See below
Mode Register, Watchdog Timer and Alarm
As this is supposed to replace an industrial control unit reliability is very important. Software errors
and crashes on the Rpi must be dealt with to bring it back to a known state. In micro-controller
circuits we use a watchdog timer which we reset during normal operation and if it gets above a
certain value without being reset then the microcontroller is reset.
We emulate this for the Rpi. When the Rpi boots up your supervisory program should ensure the
mode register (I2C register 0) is set. Its default configuration will not check the Rpi and any crashes
of your software or the Linux operating system on the Rpi will require somebody to power cycle the
board manually, therefore during operational conditions bits 2 and 3 of this register should be
changed from 00 to another value, ie
01 (bit2 set) which will require an I2C read to occur at least every 4 minutes.
10 (bit3 set) which will require an I2C read to occur at least every 16 minutes.
Eg if the bits are set to 01 and the board does not get a read or write request from the Raspberry Pi
within 4 minutes the board will assume the Rpi has crashed and power it off and on. Normally a full
power on reset and subsequent reboot will fix any problems in the Rpi software, however on restart
if the Rpi still fails to communicate with the board, the Rpi will be powered off again for 4 seconds
longer before powering back on. How many times the system does this depends upon bits 4 and 5 of
the mode register. The default is 00 which means the 4th time the power is reset the alarm will sound
on the board and the Rpi will be left with the 5V supplied to it, this will hopefully allow you to SSH
in to the board and fix any problems (assuming Linux is OK) the other settings of bits 4 and 5 will
allow more failures but after 4 I'm assuming it is something more serious.
A Shutdown signal is provided on GPIO pin 4 of the Rpi it will go high 10 seconds before the
power is cycled and it is recommended a monitoring program is run to monitor this and initiate a
shutdown immediately the signal goes high
Note: Hard powering off the Rpi repeatedly without issueing a shutdown could have the effect of
interrupting a write to the SD card by the operating system. While this is highly unlikely and even
more unlikely that if it is the write will be to a critical part of the system it could cause a corruption
of the SD card. If you want your device super-rugged you should use a distro that mounts the root
file system read-only. (https://hallard.me/raspberry-pi-read-only/). ToDo add power-down signal to
Rpi through GPIO so it knows its loosing power and can possibly react!! (UPS?!!)
Notes on Calibration and Manual Calculation of Temperature
If you decide to set the MODE register to read ADC raw values then your program on the RPi can calculate
the temperature using the formula below:
Temp DegC = ( ADC[n] – ADC[lo] ) x Tdiff /
Where: ADC[n]
ADC[lo]
ADC[hi]
Tdiff *
=
=
=
=
(ADC[hi] – ADC[lo] ) - 12
ADC Value of the PT100 channel you are reading
ADC Value of the low calibration resistor
ADC Value of the high calibration resistors
Temperature of Hi Calibration Resistor – Temp of Lo calibration resistor
* eg if you are using the circuit in its default configuration then the lo calibration resistor will be 95.3 ohm
which is the same as a PT100 temp of -12 DegC and the hi calibration will be 124 ohm which is 62 DegC so
Tdiff would be 74 (62 - -12)
So in a real world example, when I was testing I used a 95.3 ohm resistor as the lo calibration resistor and
this equated to -12 DegC, I used a 124 ohm resistor (equates to 62DegC) so:
Channel 4
ADC[4]
had an ADC reading of 25018
lo calib ADC[lo]
had an ADC reading of 22560
hi calib ADC[hi]
had an ADC reading of 28931
(it is a 12-bit ADC but system uses average*8 value internally to minimize division errors)
Tdiff
ADC[n]
ADC[lo]
ADC[hi]
= 74
= 25018
= 22560
= 28931
Temp DegC
= (25018 – 22560) * 74 / (28931 – 22560) - 12
Temp DegC
= 181892 / 6371 = 16.5 DegC
Notes
1. In the firmware Vref to the constant current generator comes from the DAC on the PIC16. On Power on of
the Pic and before power is applied to the Rpi we select the 124 ohm (+62 DegC) channel and adjust Vref
automatically up close to the FSD of the ADC, this gives optimal performance from the analog circuitry and
ADC. It is recommended in most publications you do not send more than 1mA to the PT100 to keep self
heating low, however as we are only polling each channel 1/8th of the time it is not an issue to go a lot higher
if required.
2. The analog circuitry is kept on the reverse of the PCB from the digital circuitry, they also use different
ground planes and a more filtrered supply, however there is still some noise from the digital side (including
the real noisy Rpi!) and it is good practice to do some sort of averaging in the firmware to offset this.
I have done a simple AVG() function which gives me the average ADC reading over 64 reads. Note the C
code for the firmware tries to use integer math as the PIC16 and XC8 compiler are pretty crap at math so it
may be better to do this on the Rpi and/or in a higher level language.
3. A proper earth to the GND/0V and physically grounding the case will also help reduce noise.
Testing
The test program below will do a basic test of reading temperatures and setting relays (to compile it requires
the wiringpi library to be copied into working dir) Compile it on the command line using:
g++ vtest.cpp -lwiringPi
This produces executable file a.out in the working directory which you can run by typing ./a.out
The source code to vtest.cpp is below
#include <iostream>
#include <iomanip>
#include <cstring>
#include <errno.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
using namespace std;
int main(int argc, char *argv[])
{
int fd, val16, val8, i, j;
int pass = 0;
int mode = 0x00;
int v[8];
float f;
fd = wiringPiI2CSetup(5);
if(argc>1) // take mode value from command line
{
// first argument is the temperature setting
if(strcmp(argv[1],"01") == 0) mode = mode | 0x01;
if(strcmp(argv[1],"10") == 0) mode = mode | 0x02;
if(strcmp(argv[1],"11") == 0) mode = mode | 0x03;
if(argc>2)
{
// second argument is the watchdog timer setting
if(strcmp(argv[2],"01") == 0) mode = mode | 0x04;
if(strcmp(argv[2],"10") == 0) mode = mode | 0x08;
if(strcmp(argv[2],"11") == 0) mode = mode | 0x0C;
}
if(argc>3)
{
// third argument is the failure setting
if(strcmp(argv[3],"01") == 0) mode = mode | 0x10;
if(strcmp(argv[3],"10") == 0) mode = mode | 0x20;
if(strcmp(argv[3],"11") == 0) mode = mode | 0x30;
}
}
wiringPiI2CWriteReg8(fd,0,mode);
cout << "Vinwizard PT100 Temperature Control board" << endl << endl;
while(1)
{
mode = wiringPiI2CReadReg8(fd,0) & 0x03;
val16 = wiringPiI2CReadReg16(fd,37);
cout << "Pass " << pass++ << ": MODE = " << mode << ". Up Time = " << val16 << " Hours" << endl
<< endl;
for(i=1; i<7; i++)
{
v[i] = wiringPiI2CReadReg16(fd, (i*2)-1);
cout << "PT100 Channel " << i << " = " << v[i];
if(mode==0)
{
if(v[6]-v[5]>0)
{
f = ((v[i]-v[5])*74/(v[6]-v[5])) - 12;
if(f>-30 && f<90)
cout << " ADC (Temp = " << std::setprecision(4) << f << " DegC)";
else
cout << " N/C";
}
}
if(mode==1)
{
f = v[i]/20 - 40;
if(f>-30 && f<90)
cout << " MLP Format (Temp = " << f << " DegC)";
else
cout << " N/C";
}
cout << endl;
}
delay(10);
wiringPiI2CWriteReg8(fd,21,pass%12==1);
delay(10);
wiringPiI2CWriteReg8(fd,22,pass%12==2);
delay(10);
wiringPiI2CWriteReg8(fd,23,pass%12==3);
delay(10);
wiringPiI2CWriteReg8(fd,24,pass%12==4);
delay(10);
wiringPiI2CWriteReg8(fd,25,pass%12==5);
delay(10);
wiringPiI2CWriteReg8(fd,26,pass%12==6);
delay(10);
wiringPiI2CWriteReg8(fd,27,pass%12==7);
delay(10);
wiringPiI2CWriteReg8(fd,28,pass%12==8);
if(pass%12>0 && pass%12<9)
cout << endl << "Relay " << pass%12 << " Is Now Active!" << endl << endl;
else
cout << endl << "Relays Are All Off" << endl << endl;
delay(10000);
}
}
when compiled copy a.out to vtest using
cp a.out vtest
I wont bother explaining the code, it was just mostly copied from examples in the wiring Pi sites. Modes can
be set by passing the three bit settings of MODE on the command line. Running vtest on a normal system
gives the following output
Note we have passed 01 to the program to give the output in MLP format. On this board ch1 was wired to a
100 ohm 0.1% resistor and should be 0 DegC (actual value 798 if you do the MLP calculation above is not -1
it is -0.1DegC bloody rounding*) and Channel3 is wired to a 133 ohm resistor and correctly shows 84 DegC,
channel 4 is wired to a real PT100
* I am not sure why its not showing the decimals on the temperature above i'm not really a C++ person! I
am sure Python will be much better and easier!
PCB Notes
1. Anti-Static precautions must be taken when handling the MOSFETS and IC's
2. Care should be taken to avoid shorting tracks during installation.
3. The +24V Power should be the first wire removed and the last wire attached. All changes to wiring
should be done with the 24V power removed.
4. The PTC fuse should be 1500mA, 24V
5. 12V can also be used in place of 24V but the relays must be changed to the 12V equivelemt and the
1K power supply resistor the 78L33 must be reduced to 270 ohm or removed
6. Regulator does not require heat sink, no parts on the PCB should get warm however the electronics
should not be completely sealed
7. Components must be genuine and purchased from reputable suppliers to avoid counterfit parts
compromising the circuit. Care should especially be taken on the analog components where the
resistors must all be of 0.1% tollerence and thermally stable <50ppm
Circuit Notes
Note MOSFETS and the PIC MCU are static sensitive devices and appropriate handling precautions
should be made during construction and maintenance.
The system will operate on 24VDC ripple from this supply should be <50mV
Ensure the +24V and ground are correctly connected as there is no protection diode.
The ICSP connector is for programming the PIC, a connector is not required as the pins on the PCB are
staggered and should hold the PICKit programmer header pin for the few seconds it takes to program the
MPU.
Application
The system is intended to be controlled and monitored by a SCADA system