//
/*
mltask.c: XidarML tasks.
Copyright (c) 1996 Eliot W. Dudley. All rights reserved.
edudley@servtech.com
XIDAR
3388 STATE RT 370
CATO NY 13033
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the README file.
*/
/*
1-Wire, DS, DS1820, DS2405, DS2407, DS9097, and MicroLan
are trademarks and/or registered trademarks of
Dallas Semiconductor Coporation
*/
//=============================================================================
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "util.h"
#include "mlfnc.h"
#include "ml.h"
#include "mld.h"
#include "mlerr.h"
//=============================================================================
//=============================================================================
#define T1820_SIZ 0x0200
//=============================================================================
//=============================================================================
//
/*/
A simple demo of a XidarML task object that fires up and logs temperature
readings from a DS1820. The original ml.rc command line would have
been something like:
spawn t1820log chickencoop tmlq tmlmsg chickencoop /data/temperature 1800
Which means start a task object using function T1820Log() and
pass it the command:
chickencoop tmlq tmlmsg chickencoop /data/temperature 1800
Which to T1820Log means to start a task named 'chickencoop' and talk to
the task named 'tml' via message queue 'tmlq' and and message mailbox
'tmlmsg', and get data from the 1-Wire device also named 'chickencoop',
log the data to the directory '/data/temperature' in file 'chickencoop.
And log it every half hour.
Source: \URL{../mltask.c.html#TS1820Log}
*/
int
T1820Log(
char *cmd,
int pri_ret
) {
int i;
char *ptr;
pML pml;
pTCB ptcb;
int delay = 0;
char *file_name = 0;
char *name= 0;
pEVENT ptmlq = 0;
pEVENT ptmlmsg = 0;
int hist_idx = 0;
long int temp[16];
struct timeval tv[16];
pMLNODE pmlnode;
struct tm *ptm;
FILE *LOG;
MLREAD mlread;
if(0 == setjmp((ptcb = TaskCreate(&cmd, T1820_SIZ))->jmp_buf)) {
ptcb->pmsg = EventCreate(EVENT_NAME_DEFAULT, EVENT_MSG);
ptmlq = GetEventByName(Shift(&cmd));
ptmlmsg = GetEventByName(Shift(&cmd));
MALLOC(name, strlen(ptr = Shift(&cmd)) + 1, char);
strcpy(name, ptr);
MALLOC(file_name, strlen(ptr = Shift(&cmd)) + strlen(name) + 2, char);
strcat(strcat(strcpy(file_name, ptr), "/"), name);
delay = (delay = atoi((ptr = Shift(&cmd)) ? ptr : "10")) ? delay : 10;
SpawnRet(pri_ret, ptcb->name);
}
StackClr(ptcb);
if (!(ptr = VAPost(ptmlq, ptcb->pmsg, strcpy(BufNew(), "MLGetpML")))) {
Fatal(__LINE__, NULL_PTR, 0);
}
if (!(pml = *((pML *)ptr))) {
Fatal(__LINE__, NULL_PTR, 0);
}
BufDelete(ptr);
if (!(pmlnode = GetMLNodeByName(pml, name))) {
Fatal(__LINE__, NULL_PTR, 0);
}
mlread = pmlnode->pmldriver->mlread;
LOG = fopen(file_name, "a");
for (;;) {
// Wait until our device comes around.
EventPend(pmlnode->psem, 0);
for (i = 0; i < 4; ++i) {
if (0 > (mlread)(pml, pmlnode, (char *)0, 0, 0)) {
MLPathCheck(pml);
continue;
}
temp[hist_idx = (hist_idx + 1) & 7] = pmlnode->dev.ds1820.temp;
tv[hist_idx] = pmlnode->tv;
ptm = localtime((time_t *)&pmlnode->tv.tv_sec);
VAPrintf(0, (VAPRINTF)vfprintf, LOG
,"%04d%02d%02d%02d%02d%02d %.3f\n"
,ptm->tm_year + 1900
,ptm->tm_mon + 1
,ptm->tm_mday
,ptm->tm_hour
,ptm->tm_min
,ptm->tm_sec
,pmlnode->dev.ds1820.temp / 65536.0
);
fflush(LOG);
VAPrintf(0, (VAPRINTF)vfprintf, pexec->LOG
,"%04d%02d%02d%02d%02d%02d %8.3f %8.3f %s\n"
,ptm->tm_year + 1900
,ptm->tm_mon + 1
,ptm->tm_mday
,ptm->tm_hour
,ptm->tm_min
,ptm->tm_sec
,pmlnode->dev.ds1820.temp / 65536.0
,32.0 + ((1.8 / 65536.0) * pmlnode->dev.ds1820.temp)
,name
);
fflush(LOG);
break;
}
EventSched(ptmlmsg, 0);
TaskDelaySec(delay);
}
}
//=============================================================================
//=============================================================================
int
T1820CycleDetect(
char *cmd,
int pri_ret
) {
int i;
char *ptr;
char *file_name = 0;
char *name = 0;
pTCB ptcb;
pEVENT ptmlq = 0;
pEVENT ptmlmsg = 0;
pML pml;
pMLNODE pmlnode;
int delay = 0;
int hist_idx;
long int temp[16];
struct timeval tv[16];
struct tm *ptm;
long int temp_min;
long int temp_max;
long int dtemp;
long int dtemp_abs;
long int dt;
double dtemp_dt;
double deadband = 0;
int deadbandticks = 0;
int init;
MLREAD mlread;
FILE *LOG;
if(0 == setjmp((ptcb = TaskCreate(&cmd, T1820_SIZ))->jmp_buf)) {
ptcb->pmsg = EventCreate(EVENT_NAME_DEFAULT, EVENT_MSG);
ptmlq = GetEventByName(Shift(&cmd));
ptmlmsg = GetEventByName(Shift(&cmd));
MALLOC(name, strlen(ptr = Shift(&cmd)) + 1, char);
strcpy(name, ptr);
MALLOC(file_name, strlen(ptr = Shift(&cmd)) + strlen(name) + 2, char);
strcat(strcat(strcpy(file_name, ptr), "/"), name);
delay = (delay = atoi((ptr = Shift(&cmd)) ? ptr : "10")) ? delay : 10;
ptr = (ptr = Shift(&cmd)) ? ptr : "0.04";
sscanf(ptr, "%lf", &deadband);
deadbandticks = (int)(deadband * 65536.0);
SpawnRet(pri_ret, ptcb->name);
}
StackClr(ptcb);
ptr = VAPost(ptmlq, ptcb->pmsg, strcpy(BufNew(), "MLGetpML"));
pml = *((pML *)ptr);
BufDelete(ptr);
pmlnode = GetMLNodeByName(pml, name);
mlread = pmlnode->pmldriver->mlread;
LOG = fopen(file_name, "a");
for (
init = 0,
temp_min = LONG_MIN,
temp_max = LONG_MAX,
hist_idx = 0;
;
) {
// Jump the queue.
ptr = VAPost(ptmlq, ptcb->pmsg,
strcat(strcpy(BufNew(), "MLDoNode "), pmlnode->name));
BufDelete(ptr);
// Wait until our device comes around.
EventPend(pmlnode->psem, 0);
for (i = 0; i < 4; ++i) {
if (0 > (mlread)(pml, pmlnode, (char *)0, 0, 0)) {
MLPathCheck(pml);
continue;
}
dtemp = temp[hist_idx] - pmlnode->dev.ds1820.temp;
dtemp_abs = dtemp < 0 ? -dtemp : dtemp;
if (dtemp_abs > deadbandticks) {
dt =
((tv[hist_idx].tv_sec - pmlnode->tv.tv_sec) << 16) +
(((tv[hist_idx].tv_usec - pmlnode->tv.tv_usec) << 8) / (1000000>>8));
dtemp_dt = (double)dtemp/(double)dt;
hist_idx = (hist_idx + 1) & 7;
temp[hist_idx] = pmlnode->dev.ds1820.temp;
tv[hist_idx] = pmlnode->tv;
if (init) {
ptm = localtime((time_t *)&pmlnode->tv.tv_sec);
VAPrintf(0, (VAPRINTF)vfprintf, LOG
,"%04d%02d%02d%02d%02d%02d %.3f\n"
,ptm->tm_year + 1900
,ptm->tm_mon + 1
,ptm->tm_mday
,ptm->tm_hour
,ptm->tm_min
,ptm->tm_sec
,dtemp_dt
);
fflush(LOG);
VAPrintf(0, (VAPRINTF)vfprintf, pexec->LOG
,"%04d%02d%02d%02d%02d%02d %8.3f %8.3f %7.4f %s\n"
,ptm->tm_year + 1900
,ptm->tm_mon + 1
,ptm->tm_mday
,ptm->tm_hour
,ptm->tm_min
,ptm->tm_sec
,pmlnode->dev.ds1820.temp / 65536.0
,32.0 + ((1.8 / 65536.0) * pmlnode->dev.ds1820.temp)
,dtemp_dt
,name
);
fflush(pexec->LOG);
}
}
init++;
break;
}
EventSched(ptmlmsg, 0);
TaskDelaySec(delay);
}
}
//=============================================================================