Quelltext /~heha/basteln/PC/Wetterstation/telemet.zip/tenki.c

/* TENKI (jap. <Wetter>) liest Datenbytes vom Conrad-Telemetrie-Empfnger
 * an COM2 und stellt eine einfache HTML-Seite mit den Wetterdaten bereit
 *
 * Das Programm ist als Win32-Konsolen-Anwendung in Borland C 5 geschrieben,
 * bentigt keinerlei Extra-DLLs (statisch gebunden),
 * erwartet vier Umrechnungstabellen festen Namens neben der "tenki.exe"
 * (diese sollten durchaus als Konstanten ins Programm eingebaut werden)
 * und schreibt "tenki.htm" in das aktuelle Verzeichnis.
 * h#s 05/01
 */
#include <windows.h>		// SetCommState, ...
#include <stdio.h>		// printf, scanf, ...
#include <conio.h>		// kbhit, getch
#include <string.h>		// strcpy, strrchr
/*
Ein Datenrahmen umfat 14 Bytes und ist wie folgt aufgebaut:

	Byte	Daten
	----	-----
	 1	8 Bit A/D-Wert vom Eingang A (A1)
	 2	8 Bit A/D-Wert vom Eingang B (A2) Regen
	 3	8 Bit A/D-Wert vom Eingang C (A3) Windrichtung [360/256]
	 4	8 Bit A/D-Wert vom Eingang D (A4) Luftdruck [hPa(Tabelle)]
	 5	8 Bit A/D-Wert vom Eingang E (A5) Radioaktivitt [100Sv/h]
	 6	8 Bit A/D-Wert vom Eingang F (A6) Licht [Lux(Tabelle)]
	 7	8 Bit A/D-Wert vom Eingang G (A7) Feuchte [%(Tabelle)]
	 8	8 Bit A/D-Wert vom Eingang H (A8) Temperatur [C(Tabelle)]

	 9	8 Bits vom Digitalport

	10	High-Byte des Zhler-/Frequenzmesserwertes	Windgeschw.
	11	Low-Byte des Zhler-/Frequenzmesserwertes	[0.0179 m/s]

	12	Minuten-/Stundenwert der Stoppuhr
	13	Sekunden-/Minutenwert der Stoppuhr
	14	Hundertstel-/Sekundenwert der Stoppuhr

Die Zuordnung der A/D-Wandlerwerte (0...255) zu den physikalischen Megren
der von uns angebotenen Sensoren erfolgt in den meisten Fllen durch
Tabellendateien.
Die Tabellen bercksichtigen eventuelle Nichtlinearitten der Sensorkennlinien
und nehmen Rundungen vor.

Byte 12 enthlt im MSB das Stopflag (kennzeichnet den letzen Datenrahmen
und die Stoppzeit nach dem Low-High-bergang am Triggereingang).

Byte 13 enthlt im MSB das Zeitformatflag der Stoppuhr:

	0 = Minuten:Sekunden:Hundertstel
	1 = Stunden:Minuten:Sekunden

Luft die Stoppuhr lnger als eine Stunde, erfolgt automatisch das
Umschalten des Zeitformates. Luft die Stoppuhr lnger als 24 Stunden,
rollt der Stundenwert nach 23 auf 0. Dies kann zum Zhlen von Tagen
genutzt werden.
*/
const FrameGap=300U;		//Millisekunden Mindest-Lcke

BYTE incoming[14];

float kty[256],hyg[256],lux[256],baro[256];

char *argv0;

BOOL LeseTabelle(char *dateiname, float *puffer) {
//eine Tabelle (Datei) mit 256 float-Werten einlesen, mu neben der .EXE liegen
 int i;
 FILE *fh;
 char fnamebuf[256];

 strcpy(fnamebuf,argv0);
 strcpy(strrchr(fnamebuf,'\\')+1,dateiname);
 fh=fopen(fnamebuf,"rt");
 if (fh) {
  for (i=0; i<256; i++) {
   fscanf(fh,"%f",puffer++);
  }
  fclose(fh);
 }
 return fh ? TRUE : FALSE;
}

void Vorbereitung(void) {	//junbi
 LeseTabelle("kty.tab",kty);
 LeseTabelle("hyg.tab",hyg);
 LeseTabelle("lux.tab",lux);
 LeseTabelle("baro.tab",baro);
}

void Auswertung(void) {
 int windgeschw;
 static int letzte_windgeschw;
 FILE *fh;
 int h,m,s;	// vom Zeit-Diagramm
 char timestr[64];
 static char *richtung[16]={	//Norden=0, Uhrzeiger-Richtung
   "Nord","Nord-Nordost","Nordost","Ost-Nordost",
   "Ost","Ost-Sdost","Sdost","Sd-Sdost",
   "Sd","Sd-Sdwest","Sdwest","West-Sdwest",
   "West","West-Nordwest","Nordwest","Nord-Nordwest"};

// Windgeschwindigkeit vorberechnen:
// Leider hinterlt der Sender bei stehendem Flgelrad
// den letzten gemessenen Wert konstant, deshalb hier Extrawurst braten
 windgeschw=(incoming[9]<<8)+incoming[10];
 if (windgeschw==letzte_windgeschw && windgeschw<0x30) {
  letzte_windgeschw=windgeschw;
  windgeschw=0;
 }else{
  letzte_windgeschw=windgeschw;
 }

//Uhr des Senders auswerten:
 if (incoming[12]&0x80) {	//Stunden-Minuten-Sekunden
  h=incoming[11];
  m=incoming[12]&0x7F;
  s=incoming[13];
 }else{				//Minuten-Sekunden-Hundertstel
  h=0;
  m=incoming[11];
  s=incoming[12];
 }

//HTML-Datei schreiben:
 fh=fopen("tenki.htm","wt");
 if (!fh) {
  perror("TENKI konnte HTML-Datei nicht aktualisieren!");
  return;
 }
 fputs("<HTML><HEAD>\n",fh);
 fputs("<TITLE>Gymnasium-Wetter</TITLE>\n",fh);
 fputs("<meta http-equiv=\"Content-Type\" "
	"content=\"text/html;CHARSET=iso-8859-1\">\n",fh);
 fputs("<meta http-equiv=\"refresh\" "
	"content=\"1; URL=tenki.htm\">",fh);
 fputs("</HEAD><BODY>\n",fh);
 fputs("<PRE>\n",fh);
 GetTimeFormat(LOCALE_SYSTEM_DEFAULT,TIME_NOTIMEMARKER,
   NULL,NULL,timestr,sizeof timestr);
 fprintf(fh,"Uhrzeit (lokal): %s\n",timestr);
 fprintf(fh,"\nRegen (letzte Stunde): %u mm/h",incoming[1]);
 fprintf(fh,"\nWindgeschwindigkeit:   %.2g m/s",windgeschw*0.0179);
 fprintf(fh,"\nWindrichtung:          ");
 if (windgeschw) {
  fprintf(fh,"%u  ",incoming[2]*360/256);
  fputs(richtung[(BYTE)(incoming[2]+8)>>4],fh);	//mit Umlauf-Rundung
 }else{
  fputs("nicht angebbar",fh);
 }
 fprintf(fh,"\nLuftdruck:             %.0f hPa",baro[incoming[3]]);
 fprintf(fh,"\nRadioaktivitt:        %.2f Sv/h",incoming[4]*(2.5/255));
 fprintf(fh,"\nLichtintensitt:       %.0f Lux",lux[incoming[5]]);
 fprintf(fh,"\nLuftfeuchte:           %.0f %%",hyg[incoming[6]]);
 fprintf(fh,"\nTemperatur:            %.1f C",kty[incoming[7]]);
 fprintf(fh,"\n\nBeim Empfnger ist es jetzt %02d:%02d:%02d Uhr",
   h,m,s);
 fputs("\n</PRE>\n",fh);
 fputs("</BODY></HTML>\n",fh);
 fclose(fh);
}

#pragma argsused
int main(int argc, char**argv) {
 HANDLE hCom;
 DCB dcb;
 BYTE b;
 DWORD ticks;		//Millisekunden
 DWORD bytesread;
 int incounter=0;

 puts("TENKI (h#s 05/01): generiert Web-Seite aus Wetter-Daten von COM2");
 argv0=argv[0];		//Programm-Name mit Pfad

 hCom=CreateFile("COM2",
   GENERIC_READ|GENERIC_WRITE,
   FILE_SHARE_READ|FILE_SHARE_WRITE,
   NULL,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_NORMAL,
   0);
 if (hCom==INVALID_HANDLE_VALUE) {
  perror("TENKI konnte COM2 nicht ffnen");
  return(1);
 }
 BuildCommDCB("COM2: baud=2400 parity=N data=8 stop=1",&dcb);
 dcb.fDtrControl=DTR_CONTROL_ENABLE;	//Stromversorgung!
 if (!SetCommState(hCom,&dcb)) {
  perror("TENKI konnte bertragungsparameter nicht setzen");
 }
 Vorbereitung();
 puts("Es geht los! Drcke irgendeine Taste zum Beenden!");
 do{
  ticks=GetTickCount();
  ReadFile(hCom,&b,1,&bytesread,NULL);
  if ((DWORD)(GetTickCount()-ticks)>(DWORD)FrameGap) {
   printf("\n");
   incounter=0;
  }
  printf("%02X ",b);
  if (incounter<14) {
   incoming[incounter++]=b;
   if (incounter==14) {
    Auswertung();
   }
  }
 }while (!kbhit());
 getch();
 CloseHandle(hCom);
 return 0;
}

Vorgefundene Kodierung: UTF-80