//Receive Repeat Response data from Blackfin, store into an array of size response_counter void Blackfin_Echo(int response_counter) //echos # of characters expected for each command { int temp; int counter=0; rprintfInit(uart0SendByte);//change UART to bluetooth while(1) { temp=uart3GetByte();//returns -1 if no data present //rprintf("trapped!"); if (temp != -1)//if data received { rprintf("%c",temp); response[counter]=temp & 0x0F;//store values into an array, &0x0F converts ascii to char counter++; if(counter >= response_counter || temp == '\n') { rprintf("\r\n\r\n"); uartFlushReceiveBuffer(3);//flush out receive camera buffer to stop phase shifting break; } } } }
//to track green, use low U and low V //to track blue and green, use low V only //to see color space:http://en.wikipedia.org/wiki/YUV void Blackfin_Blob_Detect(int bin_value) { rprintfInit(uart3SendByte);//change UART to Blackfin uartFlushReceiveBuffer(3);//flush out receive camera buffer to stop phase shifting rprintf("vb%d",bin_value);//poll for blob of a particular bin Blackfin_Echo(99); //decode array by summing up each part, Y_top, Y_bottom, X_left, X_right; X_left=response[6]*100 + response[7]*10 + response[8]; X_right=response[10]*100 + response[11]*10 + response[12]; Y_top=response[14]*100 + response[15]*10 + response[16]; Y_bottom=response[18]*100 + response[19]*10 + response[20]; //long ints blow up in rprintf so divide by 10 pixels=(response[25]*1000 + response[26]*100 + response[27]*10 + response[28]); X_centroid=(X_left+X_right)/2; Y_centroid=(Y_top+Y_bottom)/2; //test code, output centroid rprintfInit(uart0SendByte);//change UART to bluetooth rprintf("X_left=%d, X_right=%d Y_top=%d Y_bottom=%d Pix=%d",X_left,X_right,Y_top,Y_bottom,pixels); rprintf(", X=%d Y=%d\r\n\r\n",X_centroid,Y_centroid); }
//sets the range of a color bin (0-9) //example: vc0090255000255000255 returns ##vc0 // 012345678901234567890 //sets color bin #0 using Y mean, 255, 0, 255, 0, 255 so //pixels of higher than average brightness will appear in blob search void Blackfin_Bin_Range(int bin, int y_min, int y_max, int u_min, int u_max, int v_min, int v_max) { rprintfInit(uart3SendByte);//change UART to Blackfin uartFlushReceiveBuffer(3);//flush out receive camera buffer to stop phase shifting rprintf("vc%d",bin);//start command, send bin # rprintf("%d%d%d",y_min/100,y_min%100/10,y_min%100%10); rprintf("%d%d%d",y_max/100,y_max%100/10,y_max%100%10); rprintf("%d%d%d",u_min/100,u_min%100/10,u_min%100%10); rprintf("%d%d%d",u_max/100,u_max%100/10,u_max%100%10); rprintf("%d%d%d",v_min/100,v_min%100/10,v_min%100%10); rprintf("%d%d%d",v_max/100,v_max%100/10,v_max%100%10); Blackfin_Echo(6);//maybe 5? //test code rprintfInit(uart0SendByte);//change UART to bluetooth rprintf("vc%d",bin);//start command, send bin # rprintf("%d%d%d",y_min/100,y_min%100/10,y_min%100%10); rprintf("%d%d%d",y_max/100,y_max%100/10,y_max%100%10); rprintf("%d%d%d",u_min/100,u_min%100/10,u_min%100%10); rprintf("%d%d%d",u_max/100,u_max%100/10,u_max%100%10); rprintf("%d%d%d",v_min/100,v_min%100/10,v_min%100%10); rprintf("%d%d%d\r\n",v_max/100,v_max%100/10,v_max%100%10); }
/* I believe 'vm' command response header is 8 characters - "##vmean ", and then the Y, U and V are each 4 characters, followed by the \n Luminence, Chroma Blue, Chroma Red */ void Blackfin_YUV_Mean(void) { //int temp10; rprintfInit(uart3SendByte);//change UART to Blackfin uartFlushReceiveBuffer(3);//flush out receive camera buffer to stop phase shifting rprintf("vm");//Send Blackfin command to find mean Blackfin_Echo(19); //output array /* for(temp10=0;temp10<19;temp10++) rprintf("%d ",response[temp10]); rprintf("\r\n");*/ //decode array by summing up each part Y_mean=response[8]*100 + response[9]*10 + response[10]; U_mean=response[12]*100 + response[13]*10 + response[14]; V_mean=response[16]*100 + response[17]*10 + response[18]; //stay within limits, causes send command error if its out of bounds /*if (Y_mean < 0) Y_mean=0; if (U_mean < 0) U_mean=0; if (V_mean < 0) V_mean=0; if (Y_mean > 255) Y_mean=255; if (U_mean > 255) U_mean=255; if (V_mean > 255) V_mean=255;*/ //output for testing rprintfInit(uart0SendByte);//change UART to bluetooth rprintf("Y=%d U=%d V=%d\r\n\r\n",Y_mean, U_mean, V_mean); }
int main(void) { unsigned char tempSec; get_mcusr(); // Disable the watchdog timer uartInit(); // Init both UARTs uartSetBaudRate(0,BAUD); uartSetBaudRate(1,BAUD); stdout = stdin = &uart1_str; // Init the stdout and stdin (printf, scanf...) functions stderr = &uart0_str; // Init the stderror functions i2cInit(); i2cSetBitrate(100); ds1307_enable(DS1307_I2C_ADDR); // Enable the DS1307 RTC // Make a flash on LEDs connected to PORTB when starting / restarting DDRB=0xff; // PORTB output PORTB=0xff; // All bits on port B = 1 _delay_ms(1000); // Wait until XBee modem has started PORTB=0x00; // All bits on port B = 0 // Empty the receive buffer of both UARTs uartFlushReceiveBuffer(EthUART); uartFlushReceiveBuffer(XBeeUART); wdt_enable(WDTO_2S); // Enable watchdog, reset after 2 seconds wdt_reset(); while(1) { wdt_reset(); // Reset the watchdog timer tempSec=time.sec; if(ds1307_gettime(DS1307_I2C_ADDR, &time)) { //if(tempSec!=time.sec) if((time.sec%2==0)&&(tempSec!=time.sec)) // True every 2nd second { while(!uartReceiveBufferIsEmpty(XBeeUART)) { int i; i=0; signed char XBeePacket[12]; // Read data from slave module while (i<13) { while (uartReceiveBufferIsEmpty(XBeeUART)) ;; // Syncronization uartReceiveByte(XBeeUART, &XBeePacket[i]); if (XBeePacket[i]=='~') // Counter is set to 0 if the current character is '~' i=0; if (XBeePacket[0]=='~') //Increment if the first character in received data is '~' i++; } sm[XBeePacket[7]-'0'].temp=XBeePacket[12]-7; // Compensate for heat from components in slave module // Check status of slave module and make status ready to send to webserver if (XBeePacket[10]=='f') sm[XBeePacket[7]-'0'].status=0; else if (XBeePacket[10]=='n') sm[XBeePacket[7]-'0'].status=1; XBeePacketCounter[XBeePacket[7]-'0']=1; // Set packet counter for this slave module to 1 } // Check packet counter of all modules, if false: status=2 is sent to the webserver // Webserver will then now which modules that are unconnected for (int i=0; i<noOfModules; i++) { if (!XBeePacketCounter[i]) sm[i].status=2; XBeePacketCounter[i]=0; } // Receive data from webserver if (checkForEthPacket(ethPacket)) { if (ethPacket[pHour]<24)// edit time { time.yr=ethPacket[pYear]; time.mon=ethPacket[pMonth]; time.dat=ethPacket[pDate]; time.hr=ethPacket[pHour]; time.min=ethPacket[pMin]; ds1307_settime(DS1307_I2C_ADDR,time); } int number=0; while (number<noOfModules) { sm_web[number].type=ethPacket[pType+number*pFieldsModules]; sm_web[number].status=ethPacket[pStatus+number*pFieldsModules]; sm_web[number].temp=ethPacket[pTemp+number*pFieldsModules]; switch (sm_web[number].type) { case 0: if (sm_web[number].status==0) // Check if the current slave module is disabled on the website sendSlaveModule(number,0); // Send data to slave module: turn off relay else { if ((sm[number].temp)<(sm_web[number].temp-1)) // Measured temperature < wanted temperature - 1 ? sendSlaveModule(number,1); // Send data to slave module: turn on relay else if ((sm[number].temp)>(sm_web[number].temp+1)) // Measured temperature > wanted temperature + 1 ? sendSlaveModule(number,0); // Send data to slave module: turn off relay else sendSlaveModule(number,2); // Send data to slave module } break; } number++; // next slave module } } sendEthPacket(time, sm); // send packet with data to webserver } } } return 0; }
int main(void){ uint16_t plen; uint16_t dat_p; uint8_t cmd; // set the clock speed to "no pre-scaler" (8MHz with internal osc or // full external speed) // set the clock prescaler. First write CLKPCE to enable setting of clock the // next four instructions. CLKPR=(1<<CLKPCE); // change enable CLKPR=0; // "no pre-scaler" uartInit(); uartSetBaudRate(9600); _delay_loop_1(50); // 12ms /* enable PD2/INT0, as input */ DDRD&= ~(1<<DDD2); // test button cbi(DDRD,PIND6); sbi(PORTD,PIND6); // internal pullup resistor on _delay_loop_1(50); // 12ms // read eeprom values unless, the PD6 pin is connected to GND during bootup // PD6 is used to reset to factory default. Note that factory default is // not stored back to eeprom. if (eeprom_read_byte((uint8_t *)0x0) == 19 && ! bit_is_clear(PIND,PIND6)){ // ok magic number matches accept values eeprom_read_block((uint8_t *)myip,(void *)1,sizeof(myip)); eeprom_read_block((uint8_t *)monitoredhost,(void *)6,sizeof(monitoredhost)); pinginterval=eeprom_read_byte((uint8_t *)11); sendping=eeprom_read_byte((uint8_t *)12); eeprom_read_block((char *)password,(void *)13,sizeof(password)); password[7]='\0'; // make sure it is terminated, should not be necessary } /*initialize enc28j60*/ enc28j60Init(mymac); enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz _delay_loop_1(50); // 12ms // LED /* enable PB1, LED as output */ //DDRB|= (1<<DDB1); /* set output to Vcc, LED off */ //LEDOFF; // the transistor on PD7 DDRD|= (1<<DDD7); PORTD &= ~(1<<PIND7);// transistor off /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ // LEDB=yellow LEDA=green // // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); enc28j60PhyWrite(PHLCON,0x476); _delay_loop_1(50); // 12ms //init the ethernet/ip layer: init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT); timer_init(); _delay_ms(1000); uartFlushReceiveBuffer(); sei(); // interrupt enable while(1){ //uartSendByte('a'); //checkForEthPacket(ethPacket); stop_timer=2; if (checkForEthPacket(ethPacket)) { sendEthPacket(time, sm); time.hr = 99; } stop_timer=0; // wait_data++; // if (wait_data>40) // wait_data=0; //_delay_ms(500); // spontanious messages must not interfer with // web pages if (pagelock==0 && enc28j60hasRxPkt()==0){ if (sendping && havemac==0){ client_arp_whohas(buf,monitoredhost); havemac=2; } if (sendping && havemac==1 && pingnow){ pingnow=0; client_icmp_request(buf,monitoredhost,PINGPATTERN); pingtimer++; // otheweise we would call this function again hoststatus++; if (hoststatus==0xff){ hoststatus=1; // wrap to 1 } } } // get the next new packet: plen = enc28j60PacketReceive(BUFFER_SIZE, buf); /*plen will be unequal to zero if there is a valid * packet (without crc error) */ if(plen==0){ continue; } // arp is broadcast if unknown but a host may also // verify the mac address by sending it to // a unicast address. if(eth_type_is_arp_and_my_ip(buf,plen)){ if (eth_type_is_arp_req(buf)){ make_arp_answer_from_request(buf); } if (eth_type_is_arp_reply(buf)){ if (client_store_gw_mac(buf,monitoredhost)){ havemac=1; } } continue; } // check if ip packets are for us: if(eth_type_is_ip_and_my_ip(buf,plen)==0){ continue; } if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREPLY_V){ if (buf[ICMP_DATA_P]== PINGPATTERN){ if (check_ip_message_is_from(buf,monitoredhost)){ // ping reply is from monitored host and ping was from us hoststatus=0; hostbackafterreboot=1; } } } if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ if (check_ip_message_is_from(buf,monitoredhost)){ // ping is from monitored host hoststatus=0; hostbackafterreboot=1; } // a ping packet, let's send pong make_echo_reply_from_request(buf,plen); continue; } // tcp port www start, compare only the lower byte if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT){ if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){ make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack continue; } if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){ init_len_info(buf); // init some data structures // we can possibly have no data, just ack: dat_p=get_tcp_data_pointer(); if (dat_p==0){ if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){ // finack, answer with ack make_tcp_ack_from_any(buf); } // just an ack with no data, wait for next packet continue; } if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ // head, post and other methods: // // for possible status codes see: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>")); goto SENDTCP; } if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ plen=print_webpage(buf); goto SENDTCP; } cmd=analyse_get_url((char *)&(buf[dat_p+5])); pagelock=1; // stop automatic actions until webpage is displayed // // error, default, will get overwritte in case // something else is selected: plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Error</h1>")); plen=fill_tcp_data(buf,plen,errmsg); plen=fill_tcp_data_p(buf,plen,PSTR("<br><br><a href=/>->continue</a>\n")); // for possible status codes see: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html if (cmd==1){ resethost(); plen=print_webpage_confirm(buf); } if (cmd==2){ store_in_eeprom(); plen=print_webpage_confirm(buf); } if (cmd==7){ store_in_eeprom(); plen=print_webpage_confirm(buf); reinitmac=1; } // start and stop of wd, this is not store in eeprom if (cmd==5){ pingtimer=1; // wd on plen=print_webpage_confirm(buf); } if (cmd==4){ pingtimer=0; // wd off plen=print_webpage_confirm(buf); } if (cmd==3){ plen=print_webpage_now(buf); } if (cmd==6){ plen=print_webpage_config(buf); } // testing the temp OK / NOK if (cmd==20){ sm[0].temp= atoi(strbuf); plen=print_webpage_confirm(buf); } if (cmd==21){ sm[1].temp= atoi(strbuf); plen=print_webpage_confirm(buf); } // on / off - slave-modules // ON slave-module-1 if (cmd==34){ sm[0].status = atoi(strbuf); plen=print_webpage_confirmrm1(buf); } // OFF slave-module-1 if (cmd==31){ sm[0].status = atoi(strbuf); plen=print_webpage_confirmrm1(buf); } // ON slave-module-2 if (cmd==32){ sm[1].status = atoi(strbuf); plen=print_webpage_confirmrm2(buf); } // OFF slave-module-2 if (cmd==33){ sm[1].status = atoi(strbuf); plen=print_webpage_confirmrm2(buf); } if (cmd==35){ plen=print_webpage_confirmclk(buf); } if (cmd==36){ plen=print_webpage_confirmclk(buf); } // Room-1 if (cmd==10){ plen=print_webpage_room1(buf); } // ROom-2 if (cmd==11){ plen=print_webpage_room2(buf); } // Clock & date if (cmd==12){ plen=print_webpage_clk(buf); } // SENDTCP: make_tcp_ack_from_any(buf); // send ack for http get make_tcp_ack_with_data(buf,plen); // send data continue; } } // tcp port www end // // udp not implemented } return (0); }
/* process messages coming from Commander * format = 0xFF RIGHT_H RIGHT_V LEFT_H LEFT_V BUTTONS EXT checksum_cmdr */ int CmdrReadMsgs() { //while(LISTEN.available() > 0){ while(uartReceiveBufferIsEmpty(LISTEN) == FALSE) { if(index_cmdr == -1) { // looking for new packet if(uartGetByte(LISTEN) == 0xff) { //read until packet start index_cmdr = 0; checksum_cmdr = 0; } } else if(index_cmdr == 0) { vals[index_cmdr] = (unsigned char) uartGetByte(LISTEN); if(vals[index_cmdr] != 0xff) { checksum_cmdr += (int) vals[index_cmdr]; index_cmdr++; } } else { vals[index_cmdr] = (unsigned char) uartGetByte(LISTEN); //loops will sequentially read bytes and store them here checksum_cmdr += (int) vals[index_cmdr]; index_cmdr++; // DEBUG: if all packets go through, shoudl see x2 through x7 when Commander input is being received. // rprintf("x%u ",index_cmdr); if(index_cmdr == 7) { // packet complete if(checksum_cmdr%256 != 255) { // packet error! rprintf("\npacket error!\n"); index_cmdr = -1; return 0; } else { char buttonval = vals[4]; short dowalking = zTRUE; //rprintf("\t%d\t",(int)buttonval); //Turn gait... if((buttonval&0x40) > 0) { //if(buttonval & BUT_LT){ if(PRINT_DEBUG_COMMANDER) { rprintf("lft\t"); } turnleft = zTRUE; turnright = zFALSE; dowalking = zFALSE; } else if((buttonval&0x80) > 0) { //if(buttonval & BUT_RT){ if(PRINT_DEBUG_COMMANDER) { rprintf("rgt\t"); } turnright = zTRUE; turnleft = zFALSE; dowalking = zFALSE; } else { // Do nothing turnright = zFALSE; turnleft = zFALSE; turn = zFALSE; } if((buttonval&BUT_L6) > 0) { gunbutton = zTRUE; if(PRINT_DEBUG_COMMANDER) { rprintf("guns\t"); } } else { gunbutton = zFALSE; } if((buttonval&BUT_R3) > 0) { panicbutton = zTRUE; if(PRINT_DEBUG_COMMANDER) { rprintf("panic\t"); } } else { panicbutton = zFALSE; } if((buttonval&BUT_L4) > 0) { infobutton = zTRUE; if(PRINT_DEBUG_COMMANDER) { rprintf("info\t"); } } else { infobutton = zFALSE; } if((buttonval&BUT_R2) > 0) { pan_pos = PAN_CENTER; tilt_pos = TILT_CENTER; if(PRINT_DEBUG_COMMANDER) { rprintf("look\t"); } } // else{infobutton = zFALSE;} if((buttonval&BUT_R1) > 0) { agitbutton = zTRUE; if(PRINT_DEBUG_COMMANDER) { rprintf("agit\t"); } } else { agitbutton = zFALSE; } if((southpaw&0x01) > 0) { // SouthPaw walkV = (signed char)( (int)vals[0]-128 ); walkH = (signed char)( (int)vals[1]-128 ); // lookV = (signed char)( (int)vals[2]-128 ); // lookH = (signed char)( (int)vals[3]-128 ); } else if (dowalking) { // vals - 128 gives look a vlaue in the range from -128 to 127? lookV = (signed char)( (int)vals[0]-128 ); lookH = (signed char)( (int)vals[1]-128 ); // if( (int)vals[0] >= 128){ // tilt_pos = interpolateU( (int)vals[0],128,128+102,TILT_CENTER,servo52Max); // } // else { // tilt_pos = interpolateU( (int)vals[0],128-102,128,servo52Min,TILT_CENTER); // } int pan_add = (-(float)lookH)/17; int tilt_add = (-(float)lookV)/25; pan_pos = CLAMP(pan_pos + pan_add, servo51Min, servo51Max); tilt_pos = CLAMP(tilt_pos + tilt_add, servo52Min, servo52Max); //Default handling in original Commander.c - sets to range of -127 to 127 or so... walkV = (signed char)( (int)vals[2]-128 ); walkH = (signed char)( (int)vals[3]-128 ); } // pan = (vals[0]<<8) + vals[1]; // tilt = (vals[2]<<8) + vals[3]; // buttons = vals[4]; // ext = vals[5]; } index_cmdr = -1; //LISTEN.flush(); //flush after reading an entire packet... why? uartFlushReceiveBuffer(LISTEN); return 1; } } } return 0; }
void control(void) { reset_timer5(); uartFlushReceiveBuffer(1); a2dSetReference(ADC_REFERENCE_256V); delay_us(100); PORT_OFF(PORTB,7); while(1) { char read = uart1GetByte(); if(read == 'U') { //Rangefinder only for the Hand! We only have 3 uart ports! uart0SendByte(0x22); //sends 4 bytes with the command to read distance (0x22) uart0SendByte(0x00); uart0SendByte(0x00);uart0SendByte(0x22);delay_us(50); uart0GetByte(); //we don't care about this byte rprintf("%d\r\n", 255*uart0GetByte() + uart0GetByte()); uart0GetByte(); //we don't care about this byte } else if(read == 'L') { rprintf("%d\r\n", 255 - a2dConvert8bit(0)); } else if(read == 'R') { rprintf("%d\r\n", 255 - a2dConvert8bit(1)); } else if(read == 'D') { int buff='#'; uart2SendByte('#'); uart2SendByte('o'); uart2SendByte('s'); uart2SendByte('#'); uart2SendByte('f'); delay_ms(60); // Do not change this delay or you'll get in trouble! while(1) { buff = uart2GetByte(); if(buff==10 || buff==13 || buff==-1) { uart1SendByte('\r'); uart1SendByte('\n'); break; } uart1SendByte(buff); } while((buff=uart2GetByte()) != -1); } else if(read == 'E') { int buff='#'; uart3SendByte('#'); uart3SendByte('o'); uart3SendByte('s'); uart3SendByte('#'); uart3SendByte('f'); delay_ms(60); // Do not change this delay or you'll get in trouble! while(1) { buff = uart3GetByte(); if(buff==10 || buff==13 || buff==-1) { uart1SendByte('\r'); uart1SendByte('\n'); break; } uart1SendByte(buff); } while((buff=uart3GetByte()) != -1); } else if(read == 'M') { int buff='#'; uart2SendByte('#'); uart2SendByte('o'); uart2SendByte('t'); uart2SendByte('#'); uart2SendByte('f'); delay_ms(60); // Do not change this delay or you'll get in trouble! while(1) { buff = uart2GetByte(); if(buff==10 || buff==13 || buff==-1) { uart1SendByte('\r'); uart1SendByte('\n'); break; } uart1SendByte(buff); } while((buff=uart2GetByte()) != -1); } else if(read == 'N') { int buff='#'; uart3SendByte('#'); uart3SendByte('o'); uart3SendByte('t'); uart3SendByte('#'); uart3SendByte('f'); delay_ms(60); // Do not change this delay or you'll get in trouble! while(1) { buff = uart3GetByte(); if(buff==10 || buff==13 || buff==-1) { uart1SendByte('\r'); uart1SendByte('\n'); break; } uart1SendByte(buff); } while((buff=uart3GetByte()) != -1); } else if(read == 'P') { PORT_ON(PORTB,6); } else if(read == 'p') { PORT_OFF(PORTB,6); } else if(read == 'Q') { PORT_ON(PORTB,7); } else if(read == 'q') { PORT_OFF(PORTB,7); } else if(read == 'X') { PORT_ON(PORTB,4); } else if(read == 'x') { PORT_OFF(PORTB,4); } else if(read == 'Y') { PORT_ON(PORTB,5); } else if(read == 'y') { PORT_OFF(PORTB,5); } delay_us(50); } }