Files
a2bfc/main.c
(no author) fa42e8c377 throw it all under the GPL
git-svn-id: https://svn.salfter.gotdns.org/svn/a2bfc/trunk@93 1b90f75b-8b96-4784-87c0-14078182fce6
2007-09-25 06:57:25 +00:00

332 lines
6.6 KiB
C

/*
Apple II Beer Fridge Controller
Copyright (C) 2007 Scott Alfter (scott@alfter.us)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <conio.h>
#include <errno.h>
#include <string.h>
#include <peekpoke.h>
#include <modload.h>
#include <tgi.h>
#include <stdlib.h>
#include "ow.h"
#include "ow-temp.h"
#include "ow-time.h"
#include "main.h"
COMP_STATUS compressor_status;
unsigned char* tempsensor=NULL;
unsigned char* clockdev=NULL;
unsigned char tempsamples[280];
int main (void)
{
short i, devcount;
unsigned char devs[80];
time_t t;
struct tm intime;
unsigned char setpoint=70;
unsigned char gotopoint=70;
unsigned char currtemp;
time_t shutoff=0;
unsigned char cmd;
time_t gototime=0;
time_t lastupdate=0;
for (i=0; i<280; i++)
tempsamples[i]=70;
tgi_load(TGI_MODE_280_192_6);
if (tgi_geterror()!=TGI_ERR_OK)
{
printf("tgi_load() failed\n");
exit(EXIT_FAILURE);
}
devcount=ow_enumeratedevices(devs, 10);
for (i=0; i<devcount; i++)
{
if (ow_temp_idcheck(&devs[i<<3]))
tempsensor=&devs[i<<3];
if (ow_time_idcheck(&devs[i<<3]))
clockdev=&devs[i<<3];
}
if (tempsensor==NULL || clockdev==NULL)
{
printf("Error: temperature sensor and/or clock not found.\n");
return -1;
}
clrscr();
printf("Set clock? ");
if (readYN())
{
bzero(&intime, sizeof(intime));
printf("Year? ");
intime.tm_year=readnum(0,0)-1900;
printf("Month? ");
intime.tm_mon=readnum(0,0)-1;
printf("Day? ");
intime.tm_mday=readnum(0,0);
printf("Hour? ");
intime.tm_hour=readnum(0,0);
printf("Minute? ");
intime.tm_min=readnum(0,0);
ow_time_set(clockdev, mktime(&intime));
clrscr();
}
tgi_init(); // turn on Hi-Res mode
POKE(-16301,0); // make it split-screen
drawgraph(70);
if (tgi_geterror()!=TGI_ERR_OK)
{
printf("tgi_init() failed\n");
exit(EXIT_FAILURE);
}
relayctrl(0);
gotoxy(25,20);
printf("off ");
do
{
do
{
t=ow_time_read(clockdev);
currtemp=ow_temp_read(tempsensor, OW_TEMP_FAHRENHEIT);
gotoxy(0,20);
printf("curr=%i set=%i goto=%i \n",
currtemp,
setpoint,
gotopoint);
memcpy(&intime, localtime(&t), sizeof(intime));
printf("%i/%i/%02i %02i:%02i:%02i \n",
intime.tm_mon+1,
intime.tm_mday,
intime.tm_year%100,
intime.tm_hour,
intime.tm_min,
intime.tm_sec);
printf(" \n");
if (t>lastupdate+60)
{
lastupdate=t;
drawgraph(currtemp);
}
gotoy(wherey()-1);
if (currtemp>=setpoint+2 && compressor_status==COMP_OFF)
{
if (t-shutoff>300)
{
relayctrl(1);
gotoxy(25,20);
printf("on ");
gotoxy(0,22);
}
else
{
gotoxy(25,20);
printf("wait");
gotoxy(0,22);
}
}
if (currtemp<=setpoint-2 && compressor_status==COMP_ON)
{
relayctrl(0);
shutoff=t;
gotoxy(25,20);
printf("off ");
gotoxy(0,22);
}
if (t>=gototime && gotopoint!=setpoint)
{
if (gotopoint>setpoint)
setpoint++;
else
setpoint--;
gototime=t+3600;
}
}
while (!kbhit());
cmd=cgetc();
if (cmd>96)
cmd=cmd-32;
if (cmd=='S')
{
printf("Set point? ");
gotopoint=setpoint=readnum(setpoint,1);
}
if (cmd=='G')
{
printf("Go-to point? ");
gotopoint=readnum(gotopoint,1);
gototime=t+3600;
}
}
while (cmd!=3);
relayctrl(0);
return 0;
}
int readYN()
{
unsigned char c;
time_t start;
cputc('_'); // display cursor
do
{
start=ow_time_read(clockdev);
do // wait for input, but time out after 15 seconds
{
}
while (!kbhit() && ow_time_read(clockdev)-start<15);
if (!kbhit()) // time out...return "no"
{
backup();
c='N';
cputc(c);
cputc(13);
cputc(10);
return 0;
}
c=cgetc();
if (c>96) // convert lowercase to uppercase
c=c-32;
}
while (c!='Y' && c!='N'); // yes or no only
backup();
cputc(c);
cputc(13);
cputc(10);
return (c=='Y')?1:0;
}
int readnum(int defval, unsigned char timeout)
{
unsigned char c[8];
unsigned char p=0;
int r=0;
unsigned char i;
time_t start;
bzero(c, sizeof(c));
do
{
cputc('_');
start=ow_time_read(clockdev);
do
{
}
while (!kbhit() && timeout && ow_time_read(clockdev)-start<15);
if (!kbhit() && timeout)
{
while (p>0)
{
backup();
p--;
}
backup();
printf("%i\n", defval);
return defval;
}
c[p]=cgetc();
backup();
if (c[p]==8 || c[p]==127)
{
if (p>0)
{
p--;
backup();
}
}
else
if ((c[p]>='0' && c[p]<='9') || c[p]=='-')
{
if (p<6)
cputc(c[p++]);
}
}
while (c[p]!=13);
cputc(13);
cputc(10);
for (i=0; i<p; i++)
if (c[i]!='-')
r=(r*10)+(c[i]-48);
if (c[0]=='-')
r=-r;
return r;
}
void backup()
{
gotox(wherex()-1);
cputc(' ');
gotox(wherex()-1);
return;
}
void relayctrl(unsigned char on)
{
signed int addr=-16294+(on>0);
unsigned char x=PEEK(addr);
compressor_status=(on)?COMP_ON:COMP_OFF;
return;
}
void drawgraph(unsigned char newsample)
{
unsigned int x, y;
char mkr[3]="00";
tgi_setcolor(0);
tgi_setpixel(0,yscale(tempsamples[0]));
tgi_gotoxy(0,yscale(tempsamples[0]));
for (x=1; x<280; x++)
{
tgi_lineto(x,yscale(tempsamples[x]));
tempsamples[x-1]=tempsamples[x];
}
tempsamples[279]=newsample;
for (y=30; y<=90; y+=10)
{
tgi_setcolor(1);
tgi_line(14,yscale(y),279,yscale(y));
tgi_setcolor(3);
mkr[0]=48+(y/10);
tgi_outtextxy(0,yscale(y)-4,mkr);
}
tgi_setpixel(0,yscale(tempsamples[0]));
tgi_gotoxy(0,yscale(tempsamples[0]));
for (x=1; x<280; x++)
tgi_lineto(x,yscale(tempsamples[x]));
}
int yscale(int y)
{
if (y>90) // clamp to within range
y=90;
if (y<30)
y=30;
return 5+(90-y)*5/2;
}