[vc_row][vc_column width=”1/1″][vc_tour][vc_tab title=”Project instruction” tab_id=”1389229586-1-19″][vc_column_text]This platform is to record and process the data information collected by garbage trucks. It guarantees to improve the working efficiency of this job.
General structure:
There is infrared obstacle avoidance sensor in the machine arm. When the arm gets the trash, the Spruce controls RFID to reader the tag on it and process the data. Record them into SD card. The buzzer will work to show the valid data has been input. Finish the record and processing of the data. Then, go to the next trash.
Communication between Spruce and RFID:
SD card storage format:
No. | RFID tag No. | Date |
1 | 3005FB63AC1F3841EC880467 | 2011-8-1-MON-12:00:00 |
2 | 3005FB63AC1F3841EC880467 | 2011-8-1-MON-13:00:00 |
3 | 3005FB63AC1F3841EC880467 | 2011-8-1-MON-14:00:00 |
4 | 3005FB63AC1F3841EC880467 | 2011-8-1-MON-15:00:00 |
1.2 Flow chart:
1.3 Achieve functions
- Check whether SD card has been inserted or not. If it hasn’t, the buzzer will alarm. In this case, you need to power off and re-insert the SD card.
- Infrared obstacle avoidance: only when meet the obstacle, STM32 will send commands through serial. Power saved.
- Display the data: specific to second. You have to set the time in the program.
- Read the valid tag numbers and save them into SD card.
- Establish CSV files. Save data in this format (can duplicate record data). It can be open in table format and easy for checking.
- If the valid data input successfully, the buzzer will alarm
1.4 Peripherals connection (need to consider the circuit)
- Buzzer connection:
Positive connects to STM32 5V pin
Another port of buzzer connects to pin P89 of STM32
- Infrared obstacle avoidance sensor connection:
Positive connects to STM32 5V pin
Negative connects to STM32 GND pin.
The pin with the sign S connects to pin PE9 of STM32
- RFID connection:
RFID and STM32 are connected and share the same GND
Connect to 3V power.
STM32 USART2’s TX (PA2) connects to RFID RX
STM32 USART2’s RX (PA3) connects to RFID TX[/vc_column_text][/vc_tab][vc_tab title=”Main programs” tab_id=”1389229586-2-18″][vc_column_text]void SendCmd1(void)
{
cmd_delay();//waiting receive data
USART_SendData(USART2, 0x10);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0x03);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0x01);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
}
void SendCmd2(void)
{
cmd_delay();//waiting receive data
USART_SendData(USART2, 0x10);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0x03);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0x00);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
}
void SendCmd3(void)
{
cmd_delay();//waiting receive data
USART_SendData(USART2, 0x43);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0x04);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0x01);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
USART_SendData(USART2, 0xcd);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {/* Wait until a byte is to send*/
}
}
void USART2_IRQHandler(void)
{
//uint8_t RecieveData,i;
if (USART_GetITStatus(USART2, USART_IT_RXNE) != 0)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);//clear stop sign bit.
RecieveData = USART_ReceiveData(USART2); /* Read one byte from the receive data register */
String_to_Hex();//change to characters.
//USART_SendData(USART1, RecieveData);
//while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {}
}
}
/****************************************************************/
/*
File Name: String_to_Hex
* Description : change string to hex write the sdcard
* Input : None
* Output : None
* Return : None
*/
/****************************************************************/
void String_to_Hex(void)//a hex need two string data example: A8 store the file like ‘A’and’8’
{
uint8_t value1,value2;
uint8_t Map_value=RecieveData;
value1=Map_value/16;//high
if(value1<10)
RecieveData2[count++]=Map_value/16+’0′;//high value int to hex
else
RecieveData2[count++]=Map_value/16+’7′;//high value int to hex(A,B,C,D,E,F)
value2=Map_value%16;//low
if(value2<10)
RecieveData2[count++]=Map_value%16+’0′;//low value int to hex
else
RecieveData2[count++]=Map_value%16+’7′;//low value int to hex(A,B,C,D,E,F)
}
/****************************************************************/
/*
File Name : Write_Mark(
* Description : write marks
* Input : None
* Output : None
* Return : None
*/
/****************************************************************/
/****************************************************************/
/*
File Name : Write_Mark
* Description : write marks
* Input : None
* Output : None
* Return : None
*/
/****************************************************************/
void Write_Mark(void)
{
int Mark[5],i;//Mark number group store grade.
char name[] = { “Data.csv” };//file name
char Information[]=”No.,Tag Num,Date”;
f_mount(0, &fs);//mount the logic drive letter0
res = f_open(&fsrc, name, FA_CREATE_NEW | FA_WRITE);//create file
f_open(&fsrc, name, FA_WRITE);//open write operation
f_lseek(&fsrc, fsrc.fsize); //file pointer is moved to the bottom of the file.
if(0==Information_Flag)//write the instruction information in when the instruction information bit is 0
{
Information_Flag=1;
f_write(&fsrc, &Information, sizeof(Information), &br);//write instruction information in.
f_putc(‘\n’,&fsrc);
}
Mark[0] = Mark_Num / 10000+48; //grade calculation
Mark[1] = Mark_Num % 10000 / 1000+48;// grade calculation
Mark[2] = Mark_Num % 1000 / 100+48;// grade calculation
Mark[3] = Mark_Num % 100 / 10+48;// grade calculation
Mark[4] = Mark_Num % 10+48;// grade calculation
for(i=0;i<5;i++)
{
f_putc(Mark[i], &fsrc);//write in grade
}
f_putc(‘,’,&fsrc);//separated by commas
}
/****************************************************************/
/*
File Name : Wtite_SerialNumber
* Description : write in the tag number
* Input : None
* Output : None
* Return : None
*/
/****************************************************************/
void Wtite_SerialNumber(void)
{
char Num[24];//Num data group is used to save 24 bits tag number
memcpy(Num,RecieveData2+20*sizeof(char),24*sizeof(char));//removethe first 20 bits non-tag number. Keep 24 bits tag number.
f_write(&fsrc,&Num, 24, &br);//write into SD card
f_putc(‘,’, &fsrc);// separated by commas
count=0;//re-start the storage of the received data
}
/****************************************************************/
/*
File Name : Write_Date
* Description : write in date
* Input : None
* Output : None
* Return : None
*/
/****************************************************************/
void Write_Date(void)
{
count=0;
f_lseek(&fsrc, fsrc.fsize);//move file pointer
RTC_Get();//get data time
f_write(&fsrc, &cal, sizeof(cal), &br);//write into SD card.
f_putc(‘,’, &fsrc);//separated by commas
f_putc(‘\n’, &fsrc);//change to another line
f_close(&fsrc);//close file
}
/****************************************************************/
/*
File Name : Colation
* Description : filter data
* Input : None
* Output : None
* Return : None
*/
/****************************************************************/
void Colation(void)
{
char b[] = “4405000000”;//invalid data
char c[] = “48656C6C6F”;// invalid data
char d[] = “494E545643”;// invalid data
char f[] = “3033323420”;// invalid data
char e[10] = “0”;//e data group used to store received data
memcpy(e, RecieveData2, 10 * sizeof(char));//copy the received data
if ((0 == strcmp(b, e)) || (0 == strcmp(c, e)) || (0 == strcmp(d, e))|| (0 == strcmp(f, e)))//compare to invalid data
{
C_Flag = 0;//equal to invalid data. Clear the C_Flag bit
} else
C_Flag = 1;//if not equal, change the bit to 1
count = 0;
}
//input: year //output: whether the year is leap year: 1, yes. 0, no.
u8 Is_Leap_Year(u16 year)
{
if(year%4==0) //has to be divisible by 4
{
if(year%100==0)
{
if(year%400==0)return 1;//if the finishing is 00, it has be divisible by 400
else return 0;
}else return 1;
}else return 0;
}
u8 RTC_Get_Week(u16 year,u8 month,u8 day)//back to subscript of week, 0 is Monday.
{//note: 1900 year, 2 month, 1 day is Monday
uint16_t temp2;
uint8_t yearH,yearL;
yearH=year/100;
yearL=year%100;
// if in the 21 century, the year add 100.
if (yearH>19)
yearL+=100;
// all leap years are calculated after 1900.
temp2=yearL+yearL/4;//365/7, the remainder is 1. Leap yaer, add another 1.
temp2=temp2%7;
temp2=temp2+day+table_week[month-1];
if (yearL%4==0&&month<3)//no need of adding 1 in leap year January and February. After February, it needed.
temp2–;
return(temp2%7);
}
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)//success, back to 0. Or, be back to 1.
{
u16 t;
u32 seccount=0;
if(syear<1970||syear>2099)//start second recording from 1970-1-1-00:00:00
return 1;
for(t=1970;t<syear;t++) //add all years second.
{
if(Is_Leap_Year(t))
seccount+=31622400;//leap year seconds.
else
seccount+=31536000;//normal year seconds.
}
smon-=1;
for(t=0;t<smon;t++) //add the seconds of the month before.
{
seccount+=(u32)mon_table[t]*86400;//add month seconds.
if(Is_Leap_Year(syear)&&t==1)
seccount+=86400;//add one day’s seconds more in leap year’s闰年Feb.
}
seccount+=(u32)(sday-1)*86400;//add the seconds of the dates’ before.
seccount+=(u32)hour*3600;//hour seconds.
seccount+=(u32)min*60; //minutes seconds.
seccount+=sec;//add the last second.
//following is the setting of clock.
PWR_BackupAccessCmd(ENABLE);//clear the write protection which makes the RTC and back-up register can be visited.
RTC_SetCounter(seccount);//set the initial value of RTCCounter
RTC_WaitForSynchro();//wait for the register RTC (RTC_CNT, RTC_ALR and RTC_PRL) be synchronous with RTC clock APB
RTC_WaitForLastTask();//wait the finish of the latest write operation of RTC register.
return 0;
}
u8 RTC_Get(void)
{
static uint16_t daycnt=0;
uint32_t timecount1=0;
uint32_t temp=0;
uint16_t temp1=0;
int a,b,c;//i,
timecount1=RTC_GetCounter();//get the value of the 32 bits counter which is use to store the seconds.
temp=timecount1/86400; //get days (seconds are correspond)
if(daycnt!=temp)//over one day
{
daycnt=temp;
temp1= 1970; //follow linux to time,start second recording from 1970-1-1-00:00:00
while(temp>=365)
{
if(Is_Leap_Year(temp1))//leap year
{
if(temp>=366)temp-=366;//leap years second.
else {temp1++;break;}
}
else temp-=365; //normal year
temp1++;
}
timer.year=temp1;//get year
temp1=0;
while(temp>=28)//over one month
{
if(Is_Leap_Year(timer.year)&&temp1==1)//current year is not leap year/Feb.
{
if(temp>=29)
temp-=29;//seconds of leap year
else break;
}
else
{
if(temp>=mon_table[temp1])
temp-=mon_table[temp1];//normal year
else break;
}
temp1++;
}
timer.month=temp1+1;//get monty
timer.day=temp+1; //get date
}
temp=timecount1%86400; //get second
timer.hour=temp/3600; //hour
timer.min=(temp%3600)/60; //minute
timer.sec=(temp%3600)%60; //second
timer.week=RTC_Get_Week(timer.year,timer.month,timer.day);//get week
cal[0]=’2′;//Timer.year/1000+48; number changes to character a=a+48;
a=(timer.year-2000)/100;
cal[1]=(timer.year-2000)/100+48;
b=(timer.year-2000-a*100)/10;
cal[2]=(timer.year-2000-a*100)/10+48;
c=(timer.year-2000-a*100-b*10);
cal[3]=(timer.year-2000-a*100-b*10)+48;
//month
cal[4]=’-‘;
a=timer.month/10;
cal[5]=(timer.month/10)+48;
cal[6]=timer.month-a*10+48;
cal[7]=’-‘;
//day
a=timer.day/10;
cal[8]=(timer.day/10)+48;
cal[9]=(timer.day-a*10)+48;
cal[10]=’-‘;
//week, week recording is from Sunday.
switch(timer.week)
{
case 1://
cal[11]=week[0];
cal[12]=week[1];
cal[13]=week[2];
break;
case 2://
cal[11]=week[3];
cal[12]=week[4];
cal[13]=week[5];
break;
case 3://
cal[11]=week[6];
cal[12]=week[7];
cal[13]=week[8];
break;
case 4://
cal[11]=week[9];
cal[12]=week[10];
cal[13]=week[11];
break;
case 5://
cal[11]=week[12];
cal[12]=week[13];
cal[13]=week[14];
break;
case 6://
cal[11]=week[15];
cal[12]=week[16];
cal[13]=week[17];
break;
case 0://
cal[11]=week[18];
cal[12]=week[19];
cal[13]=week[20];
break;
default:
USART_print(“this is a bug”);
break;
}
cal[14]=’-‘;
//hour
a=timer.hour/10;
cal[15]=(timer.hour/10)+48;
cal[16]=(timer.hour-a*10)+48;
cal[17]=’:’;
//mini
a=timer.min/10;
cal[18]=(timer.min/10)+48;
cal[19]=(timer.min-a*10)+48;
cal[20]=’:’;
//sec
a=timer.sec/10;
cal[21]=(timer.sec/10)+48;
cal[22]=(timer.sec-a*10)+48;
return 0;
}
[/vc_column_text][/vc_tab][/vc_tour][/vc_column][/vc_row]
Leave a Reply
You must be logged in to post a comment.