📄 toaster.c
字号:
/* File: toaster.c
Date: 8 October 2004
Description: Program for polling toaster for temperature
and writing to standard output. */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "serial.h"
/* wait_for_prompt: wait for the toaster ready to recceive the
* common.*/
void wait_for_prompt(FILE *port)
{
char ch;
// check until the toaster send '>' to the computer
do{
ch = fgetc(port);
}
while(ch != '>');
}
/* getTemperature: Get the digital temputer from the toaster.*/
float getTemperature (FILE *port, int channel)
{
char buffer[10];
float temperature;
while(1)
{
// Ask for temperature from channel.
fprintf(port,"T%d\n",channel);
fflush (port);
// waitting for the temperature line
fgets (buffer,10,port);
fgets (buffer,10,port);
if (sscanf(buffer,"T%d %f",&channel,&temperature) == 2)
return temperature;
}
}
/* store_temp: store the latest temperature sample 'latest' in the
* array 'temp_buffer', which has 'length' elements. All previous
* temperatures are moved to the next higher subscript and the
* oldest is lost. */
void store_temp (float *temp_buffer, unsigned int length, float latest)
{
int i;
for (i = 1; i < length; i++)
temp_buffer[i] = temp_buffer[i - 1];
temp_buffer[0] = latest;
}
/* Decide the heater heating rate.
Details described in the report*/
int heaterSet (float *temp_buffer,float setpoint_temperature,float temperature)
{
int heater_setting;
float distance = 1;
float agnle = 1;
int turbo = 250;
float temp_rate = (3*temp_buffer[0]-4*temp_buffer[1]+temp_buffer[2])/2;
distance = (setpoint_temperature - temperature)/(setpoint_temperature -25);
agnle = (0.35 - temp_rate) / 0.35;
if (temperature < 25)
heater_setting = 100;
else if (distance < -0.06)
heater_setting = 0;
else if (distance < 0.15 )
{
if (temp_rate > 0)
heater_setting = 3;
else if (temp_rate > -0.02)
heater_setting = distance*((25-12)/0.1) + 12;
else if (temp_rate < -0.35)
heater_setting = 100;
else
heater_setting = (temp_rate + 0.02)/(-0.03 + 0.02)*(30 - 20);
}
else
{
if (temp_rate > 0.35 )
heater_setting = 0;
else
heater_setting = turbo * distance * agnle;
}
// make sure the heat rate is legal!
if (heater_setting > 100)
return 100;
else if(heater_setting < 0)
return 0;
else
return heater_setting;
}
/* use the heater heating rate to heat the toaster.*/
void heating (FILE *port, int channel,int heater_setting)
{
char buffer[10];
// send the common to the toaster.
fprintf(port,"H%d %d\n",channel,heater_setting);
fflush (port);
// wait for the information send by the toaster.
fgets (buffer,10,port);
fgets (buffer,10,port);
}
/* Print out the data to a file.*/
void output (FILE *out_file, int heater_setting, float temperature)
{
fprintf(out_file,"%d %2.2f\n",heater_setting,temperature);
fflush (out_file);
}
/* wait for the delay time (1 second).*/
void delay(int delay)
{
time_t ref_time = time(NULL);
while (difftime(time(NULL),ref_time) < delay){}
}
int main (int argc, char **argv)
{
FILE *serial;
FILE *out_file;
float setpoint_temperature = 40;
float start_temperature = 25;
int num_temp_sample = 300;
int channel = 0;
char *serial_devicename = "/dev/com2";
char *output_filename = "temp.dat";
float temperature;
float temp_buffer[3];
int heater_setting = 100;
// check the length of argv.
if (argc != 7)
{
fprintf(stderr, "The arguments are too few OR too more!!!\n");
return 1;
}
//store the argv to the variable
else
{
setpoint_temperature = atof(argv[1]);
start_temperature = atof(argv[2]);
num_temp_sample = atoi(argv[3]);
channel = atoi(argv[4]);
serial_devicename = argv[5];
output_filename = argv[6];
}
if(setpoint_temperature < 25 || setpoint_temperature > 50)
{
fprintf(stderr, "The setpoint temperature %2.2f is out of range.\n"
,setpoint_temperature);
return 2;
}
else if (start_temperature < 25 || start_temperature > 50)
{
fprintf(stderr, "The start temperature %2.2f is not correct.\n"
,start_temperature);
return 3;
}
else if (num_temp_sample <= 0 || num_temp_sample >=1000)
{
fprintf(stderr,"The number of temperature is out of range");
return 4;
}
else if ( channel < 0 || channel >15)
{
fprintf(stderr,"Out of the channel range.");
return 5;
}
/* Open stream for reading and appending. */
serial = fopen (serial_devicename, "a+");
if (!serial)
{
fprintf (stderr, "Could not open %s\n.",
serial_devicename);
return 6;
}
/* Configure serial port for 9600 baud. */
if (!serial_configure (serial, 9600))
{
fprintf (stderr, "Could not configure %s\n.",
serial_devicename);
return 6;
}
out_file = fopen(output_filename,"a+");
if (!serial)
{
fprintf (stderr, "Could not open %s\n.",
output_filename);
return 7;
}
// check if the toaster is ready.
fprintf(serial,"\n");
fflush (serial);
wait_for_prompt(serial);
while (1)
{
// get the temperature.
temperature = getTemperature (serial, channel);
// check the prompt, if ready for next time.
wait_for_prompt(serial);
// store the last 3 temperatures to buffer.
store_temp (temp_buffer, 3, temperature);
// set the heating rate.
heater_setting = heaterSet (temp_buffer,setpoint_temperature,temperature);
// print the data to the screen.
printf("%3d\t%2.2f\n",heater_setting,temperature);
// heat the toaster.
heating (serial, channel,heater_setting);
// record the data to a file after the temperature reach
// the start_temperature.
if (temperature >= start_temperature)
{
output (out_file, heater_setting, temperature);
num_temp_sample --;
}
// stop the program when record the num_temp_sample.
if (num_temp_sample == 0)
break;
delay(1);
}
fclose (out_file);
fclose (serial);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -