Back To Env

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 );
}