I'm still working out the bugs in the program, It'll probably change a little.
/*H********************************************************************
* Arduino Nano Env Server: Tracks 2 DHT22s and RS485 as a slave
* Uses Alt serial for 485
***********************************************************************/
#include <AltSoftSerial.h>
#include <dht.h>
#include <stdarg.h> // SO VA_ARGS WILL WORK
#include <stdio.h> // SO VA_ARGS WILL WORK
//****************** DEFINES ***********************
// #define DEBUG 1
#define LED 13
#define DHTINT 6
#define DHTEXT 5
#define DHTTYP DHT22
#define COMTX 9 // TO V8
#define COMRX 8 // FROM V8
#define ENATX 7
#define DHTDLY 2000
#define SBUFSIZ 128
#define NL 10
#define CRUNCH '#'
#define COMNBR 1 // 485 BUS SLAVE NBR
#define OK 1
#define NOTFND 0
#define ERR -1
#define SLASH '/'
#define COMBAUD 31250 // 9600, 14400, 19200, 28800
#define SERBAUD 9600 // 31250, 38400, 57600, 115200
#define pntf(_fmt,...) _pntf((char*)__func__,(char*) _fmt,##__VA_ARGS__)
typedef unsigned long ulong;
typedef int (*pfi_t)();
//****************** PROTOTYPES ***********************
void doComReq();
void doReq( int *rndx, char *buf, bool *req );
void rdDhts();
int rdCom();
char *zotChr( char *str, char chr );
int _pntf( char *fun, char *fmt, ... );
char *zotLast( char *sp, int c );
int wtCom( char *str );
//****************** VARIABLES ***********************
AltSoftSerial Com( COMRX, COMTX ); // V8 SERIAL RX, TX
DHT DhtI( DHTINT, DHTTYP );
DHT DhtE( DHTEXT, DHTTYP );
bool ComReq = false; // SERIAL REQUEST FLAGS
float TempI, TempE, HumI, HumE; // TEMP READINGS
ulong DhtTim = 0;
int State =0, DhtSel, TxDly;
int SlvNdx =0;
int ComNdx =0;
char IoBuf[SBUFSIZ];
/*********************************************************
*
*********************************************************/
void
setup()
{
char *sp;
Serial.begin( SERBAUD ); // START SERIAL I/O TO/FROM ShopSrv
Com.begin( COMBAUD ); // START SFTW SERIAL I/O TO/FROM V8
DhtI.begin();
DhtE.begin();
memset( IoBuf, 0, sizeof( IoBuf ));
State =0;
Com.flush();
pinMode( 13, OUTPUT);
pinMode( ENATX, OUTPUT);
digitalWrite( ENATX, false ); // DISABLE RS485 TRANSMISSION
TxDly = round( 1.0 / COMBAUD * 10000000.0); // CALC 485 TX TIME/BYTE
rdDhts(); // 1st DHT READ
strcpy( IoBuf, __FILE__ );
sp = zotLast( IoBuf, SLASH );
pntf("%s: Ready, TxDLY: %d\n", sp, TxDly );
}
/*******************************************************
*
********************************************************/
void
loop()
{
ulong now;
now = millis();
if( now >= DhtTim )
rdDhts();
rdCom();
if( ComReq == true )
doComReq();
}
/*F******************************************************************
* EXECUTE Com REQ
**********************************************************************/
void //"Ti="+TempI+",Hi="+HumI+"Te="+TempE+"He="+HumE
doComReq()
{
int ndx, wtLen;
char chr, sTi[32], sHi[32], sTe[32], sHe[32];
if( !strcmp( IoBuf, "ENV" ) )
{
pntf("Got ENV CMD,\n");
dtostrf( TempI, 5, 2, sTi );
dtostrf( HumI, 5, 2, sHi );
dtostrf( TempE, 5, 2, sTe );
dtostrf( HumE, 5, 2, sHe );
sprintf( IoBuf, "#01TI=%s,HI=%s,TE=%s,HE=%s\n", sTi,sHi,sTe,sHe);
wtCom( IoBuf );
}
else
pntf("Unk Cmd [%s]\n", IoBuf);
memset( IoBuf, 0, SBUFSIZ );
ComReq = false;
IoBuf[0] = 0;
State =0;
}
/*******************************************************
* READ INTERNAL & EXTERNAL DHT22s
********************************************************/
void
rdDhts()
{
int chk;
float temp;
digitalWrite( LED, 1 ); // TURN LED ON
TempI = DhtI.readTemperature( true ); // TAKES 250MS
HumI = DhtI.readHumidity(); // TAKES 250MS
TempE = DhtE.readTemperature( true ); // TAKES 250MS
HumE = DhtE.readHumidity(); // TAKES 250MS
DhtTim = millis() + DHTDLY; // SET CLOCK FOR NEXT READ
digitalWrite( LED, 0 ); // TURN LED OFF
}
/*F******************************************************************
* RD SERIAL CHARS FROM RS-485 SERIAL
**********************************************************************/
int
rdCom() // MSG FROM SRV: "#nnENV" or "#nnENV>CmdArgs"
{
int nbr;
char chrIn, *cp, slvNbr[8];
Com.listen();
while( Com.available() )
{
chrIn = Com.read(); // RD NXT INPUT CHAR
switch( State )
{
case 0:
if( chrIn != CRUNCH )
{
Com.flush();
pntf("No Crunch, X0X\n");
break; // DISCARD CRUNCH
}
ComNdx =SlvNdx =0;
State++;
break;
case 1 ... 2:
slvNbr[SlvNdx++] = chrIn;
slvNbr[SlvNdx] = 0; // TERMINATE SLV NBR BUF
State++;
break;
default:
IoBuf[ComNdx++] = chrIn; // ADD NEW CHAR To InBuf[]
IoBuf[ComNdx] = 0; // TERMINATE IOBUF
State++;
if( chrIn == NL )
{ // RCV'D NL, END OF MSG
IoBuf[ComNdx -1] = 0; // TERMINATED IoBuf, RMV NL
cp = zotChr( IoBuf, '>'); // NO ARGS REQUIRED
nbr = atoi( slvNbr );
State =0; // RESET State FOR NEXT MSG
if( (nbr != COMNBR) )
{ // NOT FOR ME
IoBuf[0] = 0; // CLR IOBUF
Com.flush();
return( 0 ); // RTN NOT FOUND
}
ComReq = true; // SET FLAG FOR MAIN LOOP
return( OK );
} // END OF if( NL )
} // END OF 'switch'
} // END OF IF (AVAILABLE)
}
/*F******************************************************************
* WRITE A MESSAGE TO SOMEONE ON THE RS-485 NET
**********************************************************************/
int
wtCom( char *str )
{
int wtLen;
digitalWrite( ENATX, true ); // ENABLE 485 TX
Com.print( IoBuf );
wtLen = strlen( IoBuf );
delayMicroseconds( TxDly * wtLen ); // WAIT FOR BUFF TO BE SENT
Com.flush(); // WAIT FOR BUFF TO BE SENT
zotChr( IoBuf, NL );
pntf("Sent: [%s]\n", IoBuf );
digitalWrite( ENATX, false ); // DISABLE 485 TX
}
/*F******************************************************************
* ZOT A CHAR IN A CHAR ARRAY, RTRN: &NEXT CHAR
**********************************************************************/
char*
zotChr( char *str, char chr )
{
char *cp;
if( (cp = strchr( str, chr )))
*cp++ = 0; // ZOT CHAR (REPL WITH ZERO)
return( cp );
}
/*F*******************************************************
* DESC: search string 'sp', back to front, for character 'c' then zot it.
* RTRN: Pointer to char +1 else NULL.
*F********************************************************/
char*
zotLast( char *sp, int c )
{
char *cp;
if( sp )
{
for( cp = &sp[strlen( sp ) - 1]; *cp && ( cp > sp); cp-- )
{
if( *cp == c )
{
*cp = 0;
return( cp +1 );
}
}
}
return( NULL );
}
/*F******************************************************************
* DEBUG PRINTF, WORKS LIKE 'C' PRINTF
**********************************************************************/
int
_pntf( char *fun, char *fmt, ... )
{
#ifdef DEBUG
int len;
char buf[SBUFSIZ];
va_list args;
va_start( args, fmt );
vsprintf( buf, fmt, args );
va_end ( args );
Serial.print( fun );
Serial.print(": ");
Serial.print( buf );
#endif
return( 0 );
}