Use POCSAG to send telemetric data

Use POCSAG to send telemetric data

There is simple way to monitor, transmit, and create alert, (event), with a Arduino and transmit result data with POCSAG. There is a easy experimental way. Using Arduino and RFM22 board, as well you can use Si4432, you can send data on Pocsag QRG 439.9875Mhz Ham band.

I monitor temperature, with a DS18B20, and Vcc value, and create an alert if Vcc drop under 5volts.

Data are sended every one minute, or instantly if alert event.

There is the result with POC32:

Some experimentation’s with small UHF PA, RFM22 board and Arduino UNO.

Arduino Sketch:

(Please include following libraries, <PString.h> <RH_RF22.h> <Pocsag.h> <OneWire.h>)

//POCSAG Telemtric system
//Send local temperature throught DS1820
//Send local batterie level

//Library
#include <PString.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <RH_RF22.h>
#include <Wire.h>
#include <Pocsag.h>
#include <OneWire.h>
#define MAX_DS1820_SENSORS 1
OneWire ds(7); // Temperature sensor on pin 7

//Singleton instance of the radio
RH_RF22 rf22;
Pocsag pocsag;

//Analog input for vmonitor pin A0
int vmonitor = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 100000.0; //100k
float R2 = 19000.0; //10k
int value = 0;

//Temp sensor
byte addr[MAX_DS1820_SENSORS][8];
byte i, sensor;
byte present = 0;
byte data[12];
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
char buftp[20]; //store tmp before send

//Vars in the loop
int rc;
int state; // state machine for CLI input
char bell=0x07; // bell = ascii 0x07

//Var for temp and vbatt
long int dest = 777812;
long int source = 0;

unsigned long timerdatasend = millis();

void setup()
{
Serial.begin(9600);
pinMode(vmonitor, INPUT);

if (!ds.search(addr[0]))
{
Serial.println(“ALERT Temperature sensor not detected”);
trigger3();
ds.reset_search();
delay(100);
//return;
}

if (rf22.init()) {
Serial.println(“Good, RF22 init OK”);
} else {
Serial.println(“ALERT RF22 init FAILED”);
}
//HAM POCSAG is 439.9875Mhz
rf22.setFrequency(439.9875, 0.000); // subtract 30 Khz for crystal correction
rf22.setModemConfig(RH_RF22::FSK_Rb_512Fd4_5 );
rf22.setTxPower(RH_RF22_TXPOW_17DBM);
}

void loop()
{
vbatt();
temp();

if (Whole > 30.00) //check for over temperature, display an alert, default set to 40 degres C
{
Serial.println(“DEBUG: Temperature is over 45°C”);
trigger1();
}
if (vin < 4.99) //check if power drop under 5 volts, display an alert
{
Serial.println(“DEBUG: VBatt is under 5Vcc”);
trigger2();
}

if((millis()-timerdatasend)>60000) //1MIN
{
sendvcc(); //SENDING VCC
sendtmp(); //SENDING TMP
timerdatasend=millis();
}
}
//****************************************************TELEMETRIE****************************************************
// Telemetric value are sended every XX Min

void sendvcc()
{
char buffer[10];
PString str(buffer, sizeof(buffer));
str.print(“VCC “);
str.print(vin);

Serial.print(“VIN: “);
Serial.println(vin); //displaying result

rc=pocsag.CreatePocsag(dest,source,buffer,0,1);
if (!rc)
{
Serial.print(“Error in createpocsag! Error: “);
Serial.println(pocsag.GetError());
// sleep 10 seconds
delay(1000);
} else {
Serial.println(“DEBUG: VCC Data sended !”);
vin = 0.0;
rf22.send((uint8_t *)pocsag.GetMsgPointer(), pocsag.GetSize());
rf22.waitPacketSent();
delay(1000);
}
}

void sendtmp()
{
char buffer2[45];
PString str(buffer2, sizeof(buffer2));
str.print(buftp);

rc=pocsag.CreatePocsag(dest,source,buffer2,0,1);
if (!rc)
{
Serial.print(“Error in createpocsag! Error: “);
Serial.println(pocsag.GetError());
// sleep 10 seconds
delay(1000);
} else {
Serial.println(“DEBUG: TMP Data sended !”);
// char buftp[1] = 0; //store tmp before send
rf22.send((uint8_t *)pocsag.GetMsgPointer(), pocsag.GetSize());
rf22.waitPacketSent();
delay(1000);
}
}

//**************************SENSORS********************************

void vbatt()
{
value = analogRead(vmonitor); // read the value at analog input A0
vout = (value * 3.0) / 1024.0; // calculate value
vin = vout / (R2/(R1+R2)); // calculate value

Serial.print(“DEBUG: Vbatt: “);
Serial.println(vin); //displaying result

if (vin<0.09)
{ vin=0.0; //avoid parasit
}
}

void temp()
{
ds.reset();
ds.select(addr[sensor]);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(700); // init
ds.depower();
present = ds.reset();
ds.select(addr[sensor]);
ds.write(0xBE);

for ( i = 0; i < 9; i++)
{ // we need 9 bytes
data[i] = ds.read();
}

LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1;
}
Tc_100 = (TReading*100/2);

Whole = Tc_100 / 100; // separate off the whole and fractional portions
Fract = Tc_100 % 100;

sprintf(buftp, “TMP%c%d.%d”,SignBit ? ‘-‘ : ‘+’, Whole, Fract < 10 ? 0 : Fract); //TMP%c%d.%d\337C
Serial.println(buftp);
}

////////////////////////////////TRIGGER EVENT//////////////////////////////
void trigger1()
{
char buffer3[12] = “OverHeat”;

rc=pocsag.CreatePocsag(dest,source,buffer3,0,1);
if (!rc)
{
Serial.print(“Error in createpocsag! Error: “);
Serial.println(pocsag.GetError());
// sleep 10 seconds
delay(1000);
} else {
rf22.send((uint8_t *)pocsag.GetMsgPointer(), pocsag.GetSize());
rf22.waitPacketSent();
delay(1000);
}
}

void trigger2()
{
char buffer3[19] = “Alert*vcc*under*5V”;
//PString(buffer3, sizeof(buffer3), “Printing_strings”);

rc=pocsag.CreatePocsag(dest,source,buffer3,0,1);
if (!rc)
{
Serial.print(“Error in createpocsag! Error: “);
Serial.println(pocsag.GetError());
// sleep 10 seconds
delay(1000);
} else {
rf22.send((uint8_t *)pocsag.GetMsgPointer(), pocsag.GetSize());
rf22.waitPacketSent();
delay(1000);
}
}

void trigger3()
{
char buffer4[36];
PString str(buffer4, sizeof(buffer4));
str.print(“ALERT Temperature sensor not detected”);

rc=pocsag.CreatePocsag(dest,source,buffer4,0,1);
if (!rc)
{
Serial.print(“Error in createpocsag! Error: “);
Serial.println(pocsag.GetError());
// sleep 10 seconds
delay(1000);
} else {
rf22.send((uint8_t *)pocsag.GetMsgPointer(), pocsag.GetSize());
rf22.waitPacketSent();
delay(1000);
}
}