/Designs/MRAKOMER2/SW/Ondrejov/irmrak.PJT
0,0 → 1,59
[PROJECT]
Target=irmrak.HEX
Development_Mode=
Processor=0x688F
ToolSuite=CCS
 
[Directories]
Include=C:\Program Files\PICC\devices\;C:\Program Files\PICC\drivers\;
Library=
LinkerScript=
 
[Target Data]
FileList=C:\PIC\IRmrakO\irmrak.c
BuildTool=C-COMPILER
OptionString=+FM
AdditionalOptionString=
BuildRequired=1
 
[irmrak.c]
Type=4
Path=
FileList=
BuildTool=
OptionString=
AdditionalOptionString=
 
[mru-list]
1=irmrak.c
 
[Windows]
0=0000 irmrak.c 0 0 796 451 3 0
 
[Opened Files]
1=C:\PIC\IRmrakO\irmrak.c
2=
3=C:\Program Files\PICC\devices\16F88.h
4=C:\Program Files\PICC\drivers\string.h
5=C:\Program Files\PICC\drivers\stddef.h
6=C:\Program Files\PICC\drivers\ctype.h
7=C:\PIC\IRmrakTX\AX25.c
8=
[debugperif]
selected=Analog/Digital Conv
[debugram]
autoread=1
[debugeedata]
autoread=1
[debugbreak]
count=0
[pcwdebug]
watchcol0=75
[debugwatch]
count=0
[debugexpr]
expr=
sideeffects=0
[Units]
Count=1
1=C:\PIC\IRmrakO\irmrak.c (main)
/Designs/MRAKOMER2/SW/Ondrejov/irmrak.c
0,0 → 1,265
//******** Mrakomer ******************************************
#define VERSION "2.1"
#define ID "$Id: irmrak.c 124 2006-10-24 15:47:15Z kakl $"
//************************************************************
 
#include "irmrak.h"
#include <string.h>
 
#use rs232(baud=9600,parity=N,xmit=PIN_A6,rcv=PIN_A7,bits=8)
 
char VER[4]=VERSION;
char REV[50]=ID;
 
#define TRESHOLD 8 // nebo 9
// nad_diodou=H je + teplota
// pod_diodou=L je - teplota
 
#define MINUS !C1OUT // je kladny impuls z IR teplomeru
#define PLUS C2OUT // je zaporny impuls z IR teplomeru
#define HALL PIN_A4 // Hallova sonda pro zjisteni natoceni dolu
// topeni je na RB3 (vystup PWM)
 
#define MAX_TEMP 10000
 
int port; // stav brany B pro krokove motory
int j; // pro synchronisaci fazi
unsigned int8 uhel; // pocitadlo prodlevy mezi merenimi
unsigned int8 i; // pro cyklus for
unsigned int16 nn; // pocitadlo mereni
unsigned int32 timer; // casovac pro topeni
unsigned int8 topit; // na jaky vykon se ma topit?
 
unsigned int16 teplota; // prectena teplota
int1 sign; // nad nulou / pod nulou
 
// --- Jeden krok krokoveho motoru ---
void krok(int n)
{
while((n--)>0)
{
if (1==(j&1)) {port^=0b11000000;} else {port^=0b00110000;};
output_B(port);
delay_ms(50);
j++;
}
}
 
// --- Dojet dolu magnetem na cidlo ---
void dolu()
{
unsigned int8 err; // pocitadlo pro zjisteni zaseknuti otaceni
 
err=0;
while(!input(HALL)) // otoceni trubky dolu az na hall
{
krok(1);
err++;
if(40==err) // do 40-ti kroku by se melo podarit otocit dolu
{
output_B(0); // vypnuti motoru
printf("Error movement.\n\r");
err=0;
}
};
delay_ms(700); // cas na ustaleni trubky
output_B(0); // vypnuti motoru
}
 
// --- Najeti na vychozi polohu dole ---
void nula()
{
int n;
 
for (n=0; n<7; n++)
{
if (!input(HALL)) return;
krok(1);
}
}
 
// --- Precti teplotu z IR teplomeru ---
void prevod()
{
unsigned int16 t; // cas
unsigned int16 tt;
 
t=0;
while(!PLUS && !MINUS)
{
t++;
if(t>65000)
{
printf("Error thermometer.\n\r");
teplota=0;
sign=true;
return;
}
}; // ceka se na 0
 
teplota=0;
sign=false;
for(t=0;t<=MAX_TEMP;t++)
{
if(PLUS || MINUS) // ceka se na + nebo -
{
if(MINUS) sign=true;
for(tt=1;tt<=MAX_TEMP;tt++)
{
if(!PLUS && !MINUS) {teplota=tt; break;}; // ceka se na 0
}
break;
}
}
teplota=teplota*19/100; // 1 stupen celsia je asi 10us
}
 
// --- Prevod a vystup jedne hodnoty ---
void vystup()
{
delay_ms(200); // pockej na ustaleni napeti po krokovani
printf(" ");
prevod(); // precti teplotu z teplomeru
if(sign)
printf("-%Lu", teplota);
else
printf("%Lu", teplota);
}
 
//------------------------------------------------
void main()
{
setup_oscillator(OSC_4MHZ|OSC_INTRC); // 4 MHz interni RC oscilator
 
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Casovac pro PWM
setup_timer_1(T1_DISABLED);
setup_ccp1(CCP_OFF);
setup_comparator(A0_VR_A1_VR); // inicializace komparatoru
setup_vref(VREF_HIGH|TRESHOLD); // 32 kroku od 0.25 do 0.75 Vdd
 
// nastav PWM pro topeni
set_pwm1_duty(0); // Spust PWM, ale zatim s trvalou 0 na vystupu
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,100,1); // perioda
 
output_B(0); // vypnuti motoru
set_tris_B(0b00000111); // faze a topeni jako vystup
 
delay_ms(1000);
printf("Mrakomer V%s (C) 2006 KAKL\n\r", VER);
printf("%s\n\r", REV);
 
topit=0; // na zacatku netopime
 
while(true)
{
port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru
j=0; // smer dolu
dolu(); // otoc trubku do vychozi pozice dolu
 
while(!kbhit())
{
timer--;
if (0==timer) // casovac, aby se marakomer neupek
{
topit=0;
set_pwm1_duty(0); // zastav topeni
printf("H %u\n\r", topit);
};
 
if (!input(HALL)) // znovuotoceni trubky dolu, kdyby ji vitr otocil
{
set_pwm1_duty(0); // zastav topeni, aby byl odber do 1A
dolu();
set_pwm1_duty(topit); // spust topeni
}
}; // pokracuj dal, kdyz prisel po RS232 znak
 
 
uhel=getc(); // prijmi znak
if ((uhel>='a') && (uhel<='k')) // nastaveni topeni [a..k]=(0..100%)
{
topit=uhel-'a';
topit*=10;
timer=500000; // cca 11s
 
// ochrana proti upeceni
prevod();
if(sign)
{
if ((teplota <= 5) && (topit > 60)) topit=0; // do -5°C se da topit maximalne na 60%
printf("H %u;G -%Lu\n\r", topit, teplota); // zobraz hodnotu topeni (<H>eating)
}
else
{
if (teplota > 10) topit=0; // kdyz je vic jak +10°C, tak netopit
if (topit > 40) topit=0; // pokud nemrzne, tak se neda topit vic jak na 40%
printf("H %u;G %Lu\n\r", topit, teplota); // zobraz hodnotu topeni (<H>eating)
}
set_pwm1_duty(topit); // spust topeni
continue;
};
 
 
if ('m'==uhel) // standardni mereni ve trech polohach
{
prevod(); //jeden prevod na prazdno pro synchnonisaci
 
j++; // reverz, nahoru
nula();
 
printf("G"); // mereni teploty Zeme (<G>round)
vystup();
 
krok(15);
printf(";S45"); // mereni teploty 45° nad obzorem
vystup();
krok(7);
printf(";S90"); // mereni teploty v zenitu
vystup();
krok(7);
printf(";S135"); // mereni teploty 45° nad obzorem na druhou stranu
vystup();
printf("\n\r");
 
j++; // reverz
dolu();
 
continue;
}
 
 
if ((uhel>='0') && (uhel<='@')) // mereni v pozadovanem uhlu [0..;]=(0..11)
{
uhel-='0';
};
 
if(uhel>11) continue; // ochrana, abysme neukroutili draty
 
printf("A %u;", uhel); // zobraz pozadovany uhel (<A>ngle)
 
prevod(); // jeden prevod na prazdno pro synchnonisaci
 
j++; // reverz, nahoru
nula();
 
printf("G"); // mereni teploty Zeme (<G>round)
vystup();
 
printf(";S"); // mereni teploty pozadovanym smerem do vesmiru (<S>pace)
krok(12); // odkrokuj do roviny
for(i=0; i<uhel; i++) // dale odkrokuj podle pozadovaneho uhlu
{
krok(2);
};
vystup();
printf("\n\r");
 
j++; // reverz
dolu();
}
}
 
/Designs/MRAKOMER2/SW/Ondrejov/irmrak.h
0,0 → 1,5
#include <16F88.h>
#device adc=8
#fuses NOWDT,INTRC_IO, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT, NOFCMEN, NOIESO, CCPB3
#use delay(clock=4000000)
 
/Designs/MRAKOMER2/SW/Standard/AX25.c
0,0 → 1,136
//#define PTT PIN_A2 // PTT control
//#define TXo PIN_C0 // To the transmitter modulator
#define PERIODAH delay_us(222) // Halfperiod H 222;78/1200 500;430/500
#define TAILH delay_us(78)
#define PERIODAL delay_us(412) // Halfperiod L 412;345/1200 1000;880/500
#define TAILL delay_us(345)
#byte STATUS = 3 // CPUs status register
 
byte SendData[16] = {'A'<<1, 'L'<<1, 'L'<<1, ' '<<1, ' '<<1, ' '<<1, 0x60,
'C'<<1, 'Z'<<1, '0'<<1, 'R'<<1, 'R'<<1, 'R'<<1, 0x61,
0x03, 0xF0};
 
boolean bit;
int fcslo, fcshi; // variabloes for calculating FCS (CRC)
int stuff; // stuff counter for extra 0
int flag_flag; // if it is sending flag (7E)
int fcs_flag; // if it is sending Frame Check Sequence
 
void flipout() //flips the state of output pin a_1
{
stuff = 0; //since this is a 0, reset the stuff counter
if (bit)
{
bit=FALSE; //if the state of the pin was low, make it high.
}
else
{
bit=TRUE; //if the state of the pin was high make it low
}
}
 
void fcsbit(byte tbyte)
{
#asm
BCF STATUS,0
RRF fcshi,F // rotates the entire 16 bits
RRF fcslo,F // to the right
#endasm
if (((STATUS & 0x01)^(tbyte)) ==0x01)
{
fcshi = fcshi^0x84;
fcslo = fcslo^0x08;
}
}
 
void SendBit ()
{
if (bit)
{
output_high(TXo);
PERIODAH;
output_low(TXo);
PERIODAH;
output_high(TXo);
PERIODAH;
output_low(TXo);
TAILH;
}
else
{
output_high(TXo);
PERIODAL;
output_low(TXo);
TAILL;
};
}
 
void SendByte (byte inbyte)
{
int k, bt;
 
for (k=0;k<8;k++) //do the following for each of the 8 bits in the byte
{
bt = inbyte & 0x01; //strip off the rightmost bit of the byte to be sent (inbyte)
if ((fcs_flag == FALSE) & (flag_flag == FALSE)) fcsbit(bt); //do FCS calc, but only if this
//is not a flag or fcs byte
if (bt == 0)
{
flipout();
} // if this bit is a zero, flip the output state
else
{ //otherwise if it is a 1, do the following:
if (flag_flag == FALSE) stuff++; //increment the count of consequtive 1's
if ((flag_flag == FALSE) & (stuff == 5))
{ //stuff an extra 0, if 5 1's in a row
SendBit();
flipout(); //flip the output state to stuff a 0
}//end of if
}//end of else
// delay_us(850); //introduces a delay that creates 1200 baud
SendBit();
inbyte = inbyte>>1; //go to the next bit in the byte
}//end of for
}//end of SendByte
 
void SendPacket(char *data)
{
int ii; // for for
 
bit=FALSE;
 
fcslo=fcshi=0xFF; //The 2 FCS Bytes are initialized to FF
stuff = 0; //The variable stuff counts the number of 1's in a row. When it gets to 5
// it is time to stuff a 0.
 
// output_low(PTT); // Blinking LED
// delay_ms(1000);
// output_high(PTT);
 
flag_flag = TRUE; //The variable flag is true if you are transmitted flags (7E's) false otherwise.
fcs_flag = FALSE; //The variable fcsflag is true if you are transmitting FCS bytes, false otherwise.
 
for(ii=0; ii<10; ii++) SendByte(0x7E); //Sends flag bytes. Adjust length for txdelay
//each flag takes approx 6.7 ms
flag_flag = FALSE; //done sending flags
 
for(ii=0; ii<16; ii++) SendByte(SendData[ii]); //send the packet bytes
 
for(ii=0; 0 != *data; ii++)
{
SendByte(*data); //send the packet bytes
data++;
};
 
fcs_flag = TRUE; //about to send the FCS bytes
fcslo =fcslo^0xff; //must XOR them with FF before sending
fcshi = fcshi^0xff;
SendByte(fcslo); //send the low byte of fcs
SendByte(fcshi); //send the high byte of fcs
fcs_flag = FALSE; //done sending FCS
flag_flag = TRUE; //about to send flags
SendByte(0x7e); // Send a flag to end packet
}
 
 
 
/Designs/MRAKOMER2/SW/Standard/irmrak.PJT
0,0 → 1,59
[PROJECT]
Target=irmrak.HEX
Development_Mode=
Processor=0x688F
ToolSuite=CCS
 
[Directories]
Include=C:\Program Files\PICC\devices\;C:\Program Files\PICC\drivers\;
Library=
LinkerScript=
 
[Target Data]
FileList=C:\PIC\IRmrakTX\irmrak.c
BuildTool=C-COMPILER
OptionString=+FM
AdditionalOptionString=
BuildRequired=1
 
[irmrak.c]
Type=4
Path=
FileList=
BuildTool=
OptionString=
AdditionalOptionString=
 
[mru-list]
1=irmrak.c
 
[Windows]
0=0000 irmrak.c 0 0 796 451 3 0
 
[Opened Files]
1=C:\PIC\IRmrakTX\irmrak.c
2=C:\PIC\IRmrakTX\irmrak.h
3=C:\Program Files\PICC\devices\16F88.h
4=C:\Program Files\PICC\drivers\string.h
5=C:\Program Files\PICC\drivers\stddef.h
6=C:\Program Files\PICC\drivers\ctype.h
7=C:\PIC\IRmrakTX\AX25.c
8=
[debugperif]
selected=Analog/Digital Conv
[debugram]
autoread=1
[debugeedata]
autoread=1
[debugbreak]
count=0
[pcwdebug]
watchcol0=75
[debugwatch]
count=0
[debugexpr]
expr=
sideeffects=0
[Units]
Count=1
1=C:\PIC\IRmrakTX\irmrak.c (main)
/Designs/MRAKOMER2/SW/Standard/irmrak.c
0,0 → 1,254
//******** Mrakomer **********
#define VERSION "2.0"
#define ID "$Id: irmrak.c 124 2006-10-24 15:47:15Z kakl $"
//****************************
 
#include "irmrak.h"
#include <string.h>
 
#use rs232(baud=9600,parity=N,xmit=PIN_A6,bits=8)
 
#define TXo PIN_A3 // To the transmitter modulator
#include "AX25.c" // Podprogram pro prenos telemetrie
char AXstring[50]; // Buffer pro prenos telemetrie
char G[5];
char S45[5];
char S90[5];
char S135[5];
char VER[4]=VERSION;
 
#define TRESHOLD 8 // nebo 9
// nad_diodou=H je + teplota
// pod_diodou=L je - teplota
 
#define MINUS !C1OUT // je kladny impuls z IR teplomeru
#define PLUS C2OUT // je zaporny impuls z IR teplomeru
#define HALL PIN_A4 // Hallova sonda pro zjisteni natoceni dolu
// topeni je na RB3 (vystup PWM)
 
#define MAX_TEMP 10000
 
int port; // stav brany B pro krokove motory
int j; // pro synchronisaci fazi
unsigned int16 n, prodleva; // pocitadlo prodlevy mezi merenimi
unsigned int16 nn; // pocitadlo mereni
unsigned int8 topit; // na jaky vykon se ma topit?
 
unsigned int16 teplota; // prectena teplota
int1 sign; // nad nulou / pod nulou
 
void krok(int n)
{
while((n--)>0)
{
if (1==(j&1)) {port^=0b11000000;} else {port^=0b00110000;};
output_B(port);
delay_ms(40);
j++;
}
}
 
void dolu()
{
unsigned int8 err; // pocitadlo pro zjisteni zaseknuti otaceni
 
err=0;
while(!input(HALL)) // otoceni trubky dolu az na hall
{
krok(1);
err++;
if(40==err) // do 40-ti kroku by se melo podarit otocit dolu
{
output_B(0); // vypnuti motoru
sprintf(AXstring,"Error movement.");
SendPacket(&AXstring[0]);
printf("%s\n\r", AXstring);
err=0;
}
};
delay_ms(700); // cas na ustaleni trubky
output_B(0); // vypnuti motoru
}
 
void prevod()
{
unsigned int16 t; // cas
unsigned int16 tt;
 
t=0;
while(!PLUS && !MINUS)
{
t++;
if(t>65000)
{
sprintf(AXstring,"Error thermometer.");
SendPacket(&AXstring[0]);
printf("%s\n\r", AXstring);
teplota=0;
sign=true;
return;
}
}; // ceka se na 0
 
teplota=0;
sign=false;
for(t=0;t<=MAX_TEMP;t++)
{
if(PLUS || MINUS) // ceka se na + nebo -
{
if(MINUS) sign=true;
for(tt=1;tt<=MAX_TEMP;tt++)
{
if(!PLUS && !MINUS) {teplota=tt; break;}; // ceka se na 0
}
break;
}
}
teplota=teplota*19/100; // 1 stupen celsia je asi 10us
}
 
void main()
{
unsigned int8 ble;
 
setup_oscillator(OSC_4MHZ|OSC_INTRC); // 4 MHz interni RC oscilator
 
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Casovac pro PWM
setup_timer_1(T1_DISABLED);
setup_ccp1(CCP_OFF);
setup_comparator(A0_VR_A1_VR); // inicializace komparatoru
setup_vref(VREF_HIGH|TRESHOLD); // 32 kroku od 0.25 do 0.75 Vdd
 
// nastav PWM pro topeni
set_pwm1_duty(0); // Spust PWM, ale zatim s trvalou 0 na vystupu
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,100,1); // perioda
 
output_B(0); // vypnuti motoru
sprintf(AXstring,"Mrakomer V%s (C) 2006 KAKL", VER);
SendPacket(&AXstring[0]);
printf("%s\n\r", AXstring);
 
 
if(input(HALL)) // pokud na zacatku byla trubka dolu,
{ // vysilej pro nastaveni prijimace rychle za sebou 10min
for(n=0; n<(10*60); n++)
{
prevod();
if(sign)
sprintf(AXstring,"Kalibrace: n %Lu, t -%Lu", n, teplota);
else
sprintf(AXstring,"Kalibrace: n %Lu, t %Lu", n, teplota);
 
delay_ms(1000); // 1s
SendPacket(&AXstring[0]);
printf("%s\n\r", AXstring);
if(!input(HALL)) break; // pokud nekdo hne trubkou, zacni merit
}
}
 
port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru
j=0; // smer dolu
dolu(); // otoc trubku do vychozi pozice dolu
nn=0; // pocitadlo packetu
 
while(true)
{
set_tris_B(0b00000111); // faze a topeni jako vystup
set_pwm1_duty(0); // netopit
port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru
j=1; // smer, nahoru
 
delay_ms(1000); // pockej pro ustaleni napeti po vypnuti topeni
prevod(); // jeden prevod na prazdno pro synchnonisaci
 
prevod(); // zem
if(sign)
{
sprintf(G,"-%Lu", teplota);
topit=10;
if (teplota>5) topit=20;
if (teplota>10) topit=50;
if (teplota>20) topit=80;
if (teplota>30) topit=100;
}
else
{
sprintf(G,"%Lu", teplota);
topit=0;
}
 
krok(2); // sjeti z koncaku
delay_ms(1000);
krok(17); // 45 stupnu
delay_ms(200);
prevod();
if(sign)
sprintf(S45,"-%Lu", teplota);
else
sprintf(S45,"%Lu", teplota);
 
strcpy(S90,"-");
if (sign && (teplota>29))
{
krok(6); // 90 stupnu
delay_ms(300);
prevod();
if(sign)
sprintf(S90,"-%Lu", teplota);
else
sprintf(S90,"%Lu", teplota);
}
 
strcpy(S135,"-");
if (sign && (teplota>29))
{
krok(6); // 135 stupnu
delay_ms(300);
prevod();
if(sign)
sprintf(S135,"-%Lu", teplota);
else
sprintf(S135,"%Lu", teplota);
}
 
j++; // reverz
dolu(); // znovu otoc trubku dolu do vychozi pozice
 
// odeslani vysledku mereni
sprintf(AXstring,
"n %Lu;G %s;S45 %s;S90 %s;S135 %s", nn, G, S45, S90, S135);
SendPacket(&AXstring[0]);
printf("%s\n\r", AXstring);
 
if (sign && (teplota>29)) // pauza do dalsiho mereni
{
prodleva=60; // 1 min
nn++;
}
else
{
prodleva=600; // 10 min pri teplote atmosfery vyzsi jak -30 stupnu
nn+=10;
}
 
if (nn>9999) nn=0; // pocitadlo mereni modulo 10000
 
set_pwm1_duty(topit); // spust topeni
for(n=prodleva; n>0; n--) // cekej na dalsi mereni
{
delay_ms(1000);
if (!input(HALL)) // znovuotoceni trubky dolu, kdyby ji vitr otocil
{
set_pwm1_duty(0); // zastav topeni, aby byl odber do 1A
dolu();
set_pwm1_duty(topit); // spust topeni
}
}
}
}
 
/Designs/MRAKOMER2/SW/Standard/irmrak.h
0,0 → 1,5
#include <16F88.h>
#device adc=8
#fuses NOWDT,INTRC_IO, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT, NOFCMEN, NOIESO, CCPB3
#use delay(clock=4000000)