Source file: /~heha/basteln/PC/Wetterstation/telemet.zip/tenki.c

/* TENKI (jap. <Wetter>) liest Datenbytes vom Conrad-Telemetrie-Empfänger
 * an COM2 und stellt eine einfache HTML-Seite mit den Wetterdaten bereit
 *
 * Das Programm ist als Win32-Konsolen-Anwendung in Borland C 5 geschrieben,
 * benötigt 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 umfaßt 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) Radioaktivität [100µSv/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 Zähler-/Frequenzmesserwertes	Windgeschw.
	11	Low-Byte des Zähler-/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 Meßgrößen
der von uns angebotenen Sensoren erfolgt in den meisten Fällen durch
Tabellendateien.
Die Tabellen berücksichtigen eventuelle Nichtlinearitäten der Sensorkennlinien
und nehmen Rundungen vor.

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

Byte 13 enthält im MSB das Zeitformatflag der Stoppuhr:

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

Läuft die Stoppuhr länger als eine Stunde, erfolgt automatisch das
Umschalten des Zeitformates. Läuft die Stoppuhr länger als 24 Stunden,
rollt der Stundenwert nach 23 auf 0. Dies kann zum Zählen von Tagen
genutzt werden.
*/
const FrameGap=300U;		//Millisekunden Mindest-Lücke

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-Südost","Südost","Süd-Südost",
   "Süd","Süd-Südwest","Südwest","West-Südwest",
   "West","West-Nordwest","Nordwest","Nord-Nordwest"};

// Windgeschwindigkeit vorberechnen:
// Leider hinterläßt der Sender bei stehendem Flügelrad
// 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,"\nRadioaktivität:        %.2f µSv/h",incoming[4]*(2.5/255));
 fprintf(fh,"\nLichtintensität:       %.0f Lux",lux[incoming[5]]);
 fprintf(fh,"\nLuftfeuchte:           %.0f %%",hyg[incoming[6]]);
 fprintf(fh,"\nTemperatur:            %.1f °C",kty[incoming[7]]);
 fprintf(fh,"\n\nBeim Empfänger 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! Drcke 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;
}

Detected encoding: ANSI (CP1252)4
Wrong umlauts? -