void Init_mcp(void) { unsigned int config2, config1; config2 = 0x190; // Baud rate is set for 100 kHz config1 = 0b1000001000100000; /* * (I2C_ON & I2C_IDLE_CON & I2C_CLK_HLD & I2C_IPMI_DIS & I2C_7BIT_ADD & * I2C_SLW_DIS & I2C_SM_DIS & I2C_GCALL_DIS & I2C_STR_DIS & I2C_NACK & * I2C_ACK_DIS & I2C_RCV_DIS & I2C_STOP_DIS & I2C_RESTART_DIS & * I2C_START_DIS) */ // Configure I2C for 7 bit address mode OpenI2C1(config1, config2); IdleI2C1(); //Initialize MCP23017 i2c I/O expander Write23X08_17(IOCONA, 0b01111000, 0x00); Write23X08_17(GPPUA, 0x00, 0x00); // Set Pull-up resistors Write23X08_17(GPPUB, 0x1F, 0x00); // Set Pull-up resistors Write23X08_17(IPOLA, 0x00, 0x00); // I/O polarity normal Write23X08_17(IPOLB, 0x00, 0x00); // I/O polarity normal Write23X08_17(GPIOA, 0x00, 0x00); // Row is kept LOW while changing I/O Write23X08_17(GPIOB, 0x00, 0x00); // Row is kept LOW while changing I/O Write23X08_17(IODIRA, 0x00, 0x00); // Rows = inputs; Columns = outputs Write23X08_17(IODIRB, 0x1F, 0x00); // Rows = inputs; Columns = outputs }
void SetupI2C(void) { unsigned int config1; unsigned int config2; //TODO Intelligent Peripheral Management Interface? //TODO Slew Rate COntrol? //TODO SMBus Input Level? //TODO explain these settings // _DIS == disable // I2C1_ON - I2c enabled // i2c1_idle_con - stop in idle mode disabled? // i2c1_clk_hld - scl holds // _ipmi_dis - disables intelligent peripheral management interface enable bit // 7bit_add - 7 bit addresses // _slw_dis - disables slew rate control // config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_HLD & I2C1_IPMI_DIS & I2C1_7BIT_ADD & I2C1_SLW_DIS & I2C1_SM_DIS & I2C1_GCALL_DIS & I2C1_STR_DIS & I2C1_NACK & I2C1_ACK_DIS & I2C1_RCV_DIS & I2C1_STOP_DIS & I2C1_RESTART_DIS & I2C1_START_DIS); config2 = 0x0188; //With Fcy = 40Mhz, F_scl = 100kHz OpenI2C1(config1, config2); EnableIntMI2C1; }
void i2cSlaveInitialize(I2cBusConnection* i2cBusConnection) { // Avoid more than one initialization if (i2cBusConnection->opened) { writeError(I2C_SLAVE_ALREADY_INITIALIZED); return; } i2cBusConnection->opened = true; appendString(getDebugOutputStreamLogger(), "I2C Slave Write Address="); appendHex2(getDebugOutputStreamLogger(), i2cBusConnection->i2cAddress); appendCRLF(getDebugOutputStreamLogger()); if (i2cBusConnection == NULL) { // Enable the I2C module with clock stretching enabled OpenI2C1(I2C_ON | I2C_7BIT_ADD | I2C_STR_EN, BRG_VAL); // 7-bit I2C slave address must be initialised here. // we shift because i2c address is shift to the right // to manage read and write address I2C1ADD = i2cBusConnection->i2cAddress >> 1; I2C1MSK = 0; // Interruption on I2C Slave // -> Priority of I2C Slave interruption mI2C1SetIntPriority(I2C_INT_PRI_3 | I2C_INT_SLAVE); // -> Enable Interruption Flag => See the same code in interruption mI2C1SClearIntFlag(); // Enable I2C (MACRO) EnableIntSI2C1; }
void main(void) { unsigned char slave7bitAddr = 0x2A; //7-bit address of Slave. MSB=Don't care. unsigned char slaveAddrWrite = (slave7bitAddr << 1); //LSB=0, Master Write request. signed char writeStat; unsigned char message[11] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; OSCCONbits.IRCF = 0b111; //Set internal oscillator to 16mHz //Must set SCL(pin RC3)and SDA(pin RC4) as inputs and enable digital buffers. TRISCbits.TRISC3 = 1; //set input TRISCbits.TRISC4 = 1; ANSELCbits.ANSC3 = 0; //enable digital buffer ANSELCbits.ANSC4 = 0; OpenI2C1(MASTER, SLEW_OFF); //If you switch to 400kHz (see below) set SLEW_ON /* You can ignore all I2C "unable to resolve identifier" errors assuming you didn't make any typos. Don't forget the "1"'s. */ /* Now set the I2C clock speed. I2C Master always controls clock. For 400kHz use 1k pullup resistors and for 100kHz use 2.2k ohms */ SSP1ADD = 0x27; //100Khz = FOSC/(4 * (SSPADD + 1)) = 16E6/((39 + 1) * 4)note:39=0x27 //SSP1ADD = 0x09; //400Khz = FOSC/(4 * (SSPADD + 1)) = 16E6/((9 + 1) * 4) while (1) { IdleI2C1(); //Wait for bus to become idle. StartI2C1(); //Begin I2C communication IdleI2C1(); //send slave address (w/write request bit) and wait for slave to reply. do { writeStat = WriteI2C1(slaveAddrWrite); //Send address with LSB=Write if (writeStat == -1) { //Detected bus collision - More than one master? unsigned char data = SSP1BUF; //clear the buffer by reading it. SSPCON1bits.WCOL = 0; //clear the bus collision status bit } else if (writeStat == -2) { //NACK (no acknowledge rx'd) //Is the slave on and ready? Did we send the correct address? } } while (writeStat != 0); //Keep repeating until slave acknowledges. //Slave has Ack'd so we can send our Hello World message now. for (int x = 0; x <= 10; x++) { do { writeStat = (WriteI2C1(message[x])); if (writeStat == -2) { //NACK (no acknowledge rx'd) //Is the slave on and ready? Using the correct pullups? } } while (writeStat != 0); //Keep repeating until slave acknowledges. } IdleI2C1(); StopI2C1(); //Delay about 1 sec and then repeat. 1sec = ((10K*200*2)/(16E6/4) Delay10KTCYx(200); Delay10KTCYx(200); } }
void SetupI2C(void) { unsigned int I2C1CONvalue, I2C1BRGvalue; I2C1CONvalue = I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_HLD & I2C1_IPMI_DIS & I2C1_7BIT_ADD & I2C1_SLW_DIS & I2C1_SM_DIS & I2C1_GCALL_DIS & I2C1_STR_DIS & I2C1_NACK & I2C1_ACK_DIS & I2C1_RCV_DIS & I2C1_STOP_DIS & I2C1_RESTART_DIS & I2C1_START_DIS; I2C1BRGvalue = 363; // Fcy(1/Fscl - 1/1111111)-1 OpenI2C1(I2C1CONvalue, I2C1BRGvalue); IdleI2C1(); }
int main(void) { // Disable Watch Dog Timer RCONbits.SWDTEN = 0; // for LED ODCAbits.ODA6 = 0; TRISAbits.TRISA6 = 0; TRISAbits.TRISA4 = 0; TRISAbits.TRISA0 = 0; //Enable channel OpenI2C1(I2C_ON, I2C_BRG); //Setup_MPU6050(); //LDByteWriteI2C(MPU6050_ADDRESS, MPU6050_RA_PWR_MGMT_1, 0x00); SPI1Init(); SPI2Init(); LCDinit(); LCDProcessEvents(); //_05ms = false; //TimerInit(); unsigned char fifocount[2]; while (1) { if (updateScreen) { LCDProcessEvents(); updateScreen = false; } if (getFifo) { LDByteReadI2C(MPU6050_ADDRESS, MPU6050_RA_FIFO_COUNTH, &fifocount[0], 2); if (((((unsigned int) fifocount[0]) << 8) | fifocount[1]) == 1024) { //need to reset unsigned char temp = 0; LDByteReadI2C(MPU6050_ADDRESS, MPU6050_RA_USER_CTRL, &temp, 1); LDByteWriteI2C(MPU6050_ADDRESS, MPU6050_RA_USER_CTRL, 0b00000100 | temp); /* int i = 0; for(i = data_p; i < data_p+CHUNK_SIZE; i++){ rpiData.imu[i] = 0; }*/ __builtin_btg((unsigned int *) &LATA, 0); } else if (((((unsigned int) fifocount[0]) << 8) | fifocount[1]) >= 42) { LDByteReadI2C(MPU6050_ADDRESS, MPU6050_RA_FIFO_R_W, &rpiData.imu[data_p], DMP_PACKET_SIZE); __builtin_btg((unsigned int *) &LATA, 4); } getFifo = false; } __builtin_btg((unsigned int *) &LATA, 6); } return 0; }
/* * configures and starts outgoing data communication * The outgoing I2C uses MSSP1 */ int setupOutgoing() { // set pins RC14, RC15 as inputs TRISCbits.TRISC3 = 1; // SCL1 ANSELCbits.ANSC3 = 0; TRISCbits.TRISC4 = 1; // SDA1 ANSELCbits.ANSC4 = 0; // configure i2c1 for master mode @ 100 kHz CloseI2C1(); OpenI2C1(MASTER, SLEW_OFF); SSPADD = BD_RT; return (1); }
/***************************************************************************** * Function Name : encoderSetupPeripheral * Description : Setup I2C for encoders * Parameters : None * Return Value : None *****************************************************************************/ static inline void encoderSetupPeripheral(void) { //same setup as ITG3200 for compatibility unsigned int I2C1CONvalue, I2C1BRGvalue; I2C1CONvalue = I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_HLD & I2C1_IPMI_DIS & I2C1_7BIT_ADD & I2C1_SLW_DIS & I2C1_SM_DIS & I2C1_GCALL_DIS & I2C1_STR_DIS & I2C1_NACK & I2C1_ACK_DIS & I2C1_RCV_DIS & I2C1_STOP_DIS & I2C1_RESTART_DIS & I2C1_START_DIS & MI2C1_INT_PRI_6; // BRG = Fcy(1/Fscl - 1/10000000)-1, Fscl = 909KHz I2C1BRGvalue = 40; OpenI2C1(I2C1CONvalue, I2C1BRGvalue); SetPriorityIntMI2C1(6); _MI2C1IF = 0; EnableIntMI2C1; }
void I2C1_INIT(S32 v_I2Cfreq_S32, U8 v_IntConfig_U8) { /*** Local variable ***/ S32 v_Fosc_S32 = 4E6; U8 v_I2CBRG_U8 = 39; // Get the Oscillator Frequency v_Fosc_S32 = GET_FreqOsc(); // Calculate BaudRate v_I2CBRG_U8 = ((F32)v_Fosc_S32/v_I2Cfreq_S32) - ((F32)v_Fosc_S32/10000000) - 1; // Configure Interrupts ConfigIntI2C1(v_IntConfig_U8); // Open I2C with specified BaudRate OpenI2C1(I2C_ON, v_I2CBRG_U8); }
void Init_mcprobot(void) { unsigned int config2, config1; config2 = 0x190; // Baud rate is set for 100 Khz config1 = 0b1000001000100000; /* (I2C_ON & I2C_IDLE_CON & I2C_CLK_HLD & I2C_IPMI_DIS & I2C_7BIT_ADD & I2C_SLW_DIS & I2C_SM_DIS & I2C_GCALL_DIS & I2C_STR_DIS & I2C_NACK & I2C_ACK_DIS & I2C_RCV_DIS & I2C_STOP_DIS & I2C_RESTART_DIS & I2C_START_DIS);*/ OpenI2C1(config1,config2); // Configure I2C for 7 bit address mode IdleI2C1(); //Initialize MCP23017 i2c I/O expander Write23X08_17(IOCONA,0b01111000,0x02); Write23X08_17(GPPUA,0xFF,0x02); // Set Pull-up resistors Write23X08_17(GPPUB,0x00,0x02); // Set Pull-up resistors Write23X08_17(IPOLA,0x00,0x02); // I/O polarity normal Write23X08_17(IPOLB,0x00,0x02); // I/O polarity normal Write23X08_17(GPIOA,0x00,0x02); // Row is kept LOW while changing I/O Write23X08_17(GPIOB,0x00,0x02); // Row is kept LOW while changing I/O Write23X08_17(IODIRA,0xFF,0x02); // GPIOA 0/7 are the sensors Write23X08_17(IODIRB,0x00,0x02); // GPIOB 0/7 are the motors }
void i2cMasterInitialize(I2cBus* i2cBus) { OutputStream* outputStream = getDebugOutputStreamLogger(); appendString(outputStream, "Initializing I2C ..."); // Avoid more than one initialization if (i2cBus->initialized) { printI2cBus(outputStream, i2cBus); appendCRLF(outputStream); appendString(getDebugOutputStreamLogger(), "\n!!! ALREADY INITIALIZED !!!\n"); return; } i2cBus->initialized = true; #define I2C_BRG 0xC6 // 100khz for PIC32 // Configure I2C for 7 bit address mode #define I2C_CON I2C_ON i2cBus->config = I2C_CON; if (i2cBus == NULL) { OpenI2C1( // Configure I2C for 7 bit address mode. I2C_CON, // 100khz for PIC32. I2C_BRG); } else { I2C_MODULE i2cModule = getI2C_MODULE(i2cBus->port); I2CConfigure(i2cModule, I2C_ON); I2CSetFrequency(i2cModule, GetPeripheralClock(), 100000L); } WaitI2C(i2cBus); // Indicates that it's ok ! appendString(outputStream, "OK\n"); printI2cBus(outputStream, i2cBus); appendCRLF(outputStream); }
int main (void) { //CLKDIVbits.RCDIV = 0b000; FRC clock divider unsigned char accel_xh = 0x00; unsigned char accel_xl = 0x00; unsigned char accel_yh = 0x00; unsigned char accel_yl = 0x00; unsigned char accel_zh = 0x00; unsigned char accel_zl = 0x00; unsigned int _60s = 0; int g_x=0; int g_y=0; int g_z=0; // Disable Watch Dog Timer RCONbits.SWDTEN = 0; // for LED ODCAbits.ODA6 = 0; TRISAbits.TRISA6 = 0; TRISAbits.TRISA0 = 0; TRISAbits.TRISA1 = 0; TRISAbits.TRISA5 = 0; //TRISAbits.TRISA2 = 0; scl2 TRISAbits.TRISA4 = 0; //TRISAbits.TRISA3 = 0; sda2 // push button TRISAbits.TRISA7 = 1; TRISDbits.TRISD6 = 1; TRISDbits.TRISD7 = 1; TRISDbits.TRISD13 = 1; //Enable channel SPI1Init(); LCDInit(); OpenI2C1( I2C_ON, I2C_BRG ); OpenI2C2( I2C_ON, I2C_BRG ); unsigned char lcd_data1[16]; unsigned char lcd_data2[16]; Setup_MPU6050(); _05ms = false; LDByteWriteI2C(MPU6050_ADDRESS,MPU6050_RA_PWR_MGMT_1 , 0x00); //turn on IMU TimerInit(); lcd_data1[12] = ' '; lcd_data1[13] = ' '; lcd_data1[14] = ' '; lcd_data1[15] = ' '; lcd_data2[6]='y'; lcd_data2[7]=' '; lcd_data2[8]=' '; lcd_data2[9]='z'; bool accel_queue = true; while (1) { //LATAbits.LATA0 = 0; //LATAbits.LATA6 = 0; //LATAbits.LATA5 = 0; //LATAbits.LATA1 = 0; if (_60s==20000){ _60s = 0; LDWordReadI2C(FUELGAUGE_ADDRESS, FUELGAUGE_CONFIG, &bat1, &bat2); LDWordReadI2C(FUELGAUGE_ADDRESS, FUELGAUGE_SOC, &bat1, &bat2); } if(_05ms==true){ //do something _60s+=1; if(accel_queue){ LDByteReadI2C(MPU6050_ADDRESS,MPU6050_RA_ACCEL_XOUT_H , &rpiData.imu[accel_p], 6); if(rpiData.imu[accel_p]==0xff && rpiData.imu[accel_p+1]==0xff) LDByteWriteI2C(MPU6050_ADDRESS,MPU6050_RA_PWR_MGMT_1 , 0x00); //turn on IMU accel_xh=rpiData.imu[accel_p]; accel_xl=rpiData.imu[accel_p+1]; accel_yh=rpiData.imu[accel_p+2]; accel_yl=rpiData.imu[accel_p+3]; accel_zh=rpiData.imu[accel_p+4]; accel_zl=rpiData.imu[accel_p+5]; accel_p+=12; if (accel_p>=1200) accel_p=0; lcd_data1[7] = 'A'; lcd_data1[8] = 'C'; lcd_data1[9] = 'C'; lcd_data1[10] = 'E'; lcd_data1[11] = 'L'; accel_queue=false; } else{ LDByteReadI2C(MPU6050_ADDRESS,MPU6050_RA_GYRO_XOUT_H , &rpiData.imu[gyro_p], 6); accel_xh=rpiData.imu[gyro_p]; accel_xl=rpiData.imu[gyro_p+1]; accel_yh=rpiData.imu[gyro_p+2]; accel_yl=rpiData.imu[gyro_p+3]; accel_zh=rpiData.imu[gyro_p+4]; accel_zl=rpiData.imu[gyro_p+5]; gyro_p+=12; if (gyro_p>=1206) gyro_p=6; lcd_data1[7] = 'G'; lcd_data1[8] = 'Y'; lcd_data1[9] = 'R'; lcd_data1[10] = 'O'; lcd_data1[11] = ' '; accel_queue=true; } LCDwriteLine(LCD_LINE1, lcd_data1); LCDwriteLine(LCD_LINE2, lcd_data2); _05ms=false; g_x=accel_xl|accel_xh<<8; lcd_data1[0]=g_x < 0? '-' : ' '; g_x=g_x > 0 ? g_x : -g_x; g_y=accel_yl|accel_yh<<8; lcd_data2[0]=g_y < 0? '-' : ' '; g_y=g_y > 0 ? g_y : -g_y; g_z=accel_zl|accel_zh<<8; lcd_data2[10]=g_z < 0? '-' : ' '; g_z=g_z > 0 ? g_z : -g_z; lcd_data1[5]=(g_x%10)+'0'; lcd_data1[4]=(g_x/10)%10+'0'; lcd_data1[3]=(g_x/100)%10+'0'; lcd_data1[2]=(g_x/1000)%10+'0'; lcd_data1[1]=(g_x/10000)%10+'0'; lcd_data2[5]=(g_y%10)+'0'; lcd_data2[4]=((g_y/10)%10)+'0'; lcd_data2[3]=((g_y/100)%10)+'0'; lcd_data2[2]=(g_y/1000)%10+'0'; lcd_data2[1]=(g_y/10000)%10+'0'; lcd_data2[15]=(g_z%10)+'0'; lcd_data2[14]=(g_z/10)%10+'0'; lcd_data2[13]=(g_z/100)%10+'0'; lcd_data2[12]=(g_z/1000)%10+'0'; lcd_data2[11]=(g_z/10000)%10+'0'; } } return 0; }
void main(void) { PT_setup(); ANSELA = 0; //make sure analog is cleared ANSELB = 0; OpenI2C1( I2C_EN, BRG_VAL ); unsigned char cmd = 0; //command line unsigned char data = 0; //output data, digital value to be converted //unsigned char addr = 0x1C; //Thermometer sensor: 5A // SendData(0x75, addr); temp = RcvData2(addr); // while(1); // delay_ms(5000); // while(1) // run the code over and over again // { // // // start the I2C communication // StartI2C1(); // Send the Start Bit (begin of data send) // IdleI2C1(); // Wait to complete // // // write the address of the chip, defined by pins AD0 and AD1 on the MAX518 // MasterWriteI2C1 (addr); // address // IdleI2C1(); // // // while( !I2C1STATbits.ACKSTAT==0 ){} // // // write the command to tell the MAX518 to change its output on output 0 // MasterWriteI2C1 (cmd); // command line // IdleI2C1(); // while( !I2C1STATbits.ACKSTAT==0 ){} // // // wite the value to put on the output // MasterWriteI2C1(data); // output // IdleI2C1(); // while( !I2C1STATbits.ACKSTAT==0 ){} // // // end the I2C communication // StopI2C1(); // end of data send // IdleI2C1(); // Wait to complete // // // the total write time is ~285us with an I2C clock of 100 kHz // // data++; // increase the data, make a sawtooth wave as an example // // //if(data>255) { // don't have to worry about this, data is 8 bit so it will roll over automatically // // data=0; // //} // // } // end while(1) // //------- uncomment to init the uart2 -----------// // UARTConfigure(UART2, UART_ENABLE_PINS_TX_RX_ONLY); // UARTSetLineControl(UART2, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); // UARTSetDataRate(UART2, PB_FREQ, BAUDRATE); // UARTEnable(UART2, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX)); // ConfigIntUART2(UART_RX_INT_EN | UART_TX_INT_EN | UART_ERR_INT_EN | UART_INT_PR0 | UART_INT_SUB_PR0); //rxchar = 0 ; // a received character //count = 0 ; // count the number of characters // // PuTTY clrscr(); //clear PuTTY screen home(); // // By default, MPLAB XC32's libraries use UART2 for STDOUT. // // This means that formatted output functions such as printf() // // will send their output to UART2 //-----------------------------------------------// // === configure threads ========== // turns OFF UART support and debugger pin, unless defines are set // === enable system wide interrupts ======== INTEnableSystemMultiVectoredInt(); // // init the threads PT_INIT(&pt_uart); // PT_INIT(&pt_anim); // ---------- uncomment to init the tft display -----------// // tft_init_hw(); // tft_begin(); // tft_fillScreen(ILI9340_BLACK); //240x320 vertical display // tft_setRotation(0); // Use tft_setRotation(1) for 320x240 //---------------------------------------------------------// // // === set up input capture // // based on timer3 (need to configure timer 3 seperately) // OpenCapture1(IC_EVERY_RISE_EDGE | IC_INT_1CAPTURE | IC_CAP_32BIT | IC_TIMER2_SRC | IC_ON); // // turn on the interrupt so that every capture can be recorded // ConfigIntCapture1(IC_INT_ON | IC_INT_PRIOR_3 | IC_INT_SUB_PRIOR_3); // INTClearFlag(INT_IC1); // // connect PIN 24 to IC1 capture unit // PPSInput(3, IC1, RPB13); // mPORTBSetPinsDigitalIn(BIT_13); //Set port as input // // // round-robin scheduler for threads while (1) { PT_SCHEDULE(protothread_uart(&pt_uart)); //PT_SCHEDULE(protothread_anim(&pt_anim)); } } // main
void InitDisplay() { unsigned int config1 = I2C_ON | I2C_7BIT_ADD; //unsigned int config2 = 15; // Works with no pll in use unsigned int config2 = 24; delay(100); // THIS IS REQUIRED TO ALLOW THE VOLTAGE TO STABILIZE BEFORE INIT-ING THE DISPLAY ConfigIntI2C1(MI2C_INT_OFF); //Disable I2C interrupt CloseI2C1(); OpenI2C1( config1, config2); IdleI2C1(); // Assert a start condition StartI2C1(); while(_SEN); // Write the address of the slave MasterWriteI2C1(Slave); while(I2C1STATbits.TBF); //Wait till address is transmitted while(!IFS1bits.MI2C1IF); //Wait for ninth clock cycle MasterWriteI2C1(Comsend); IdleI2C1(); MasterWriteI2C1(0x38); IdleI2C1(); delay(10); MasterWriteI2C1(0x39); IdleI2C1(); delay(10); MasterWriteI2C1(0x14); IdleI2C1(); MasterWriteI2C1(0x25); IdleI2C1(); MasterWriteI2C1(0x5E); IdleI2C1(); MasterWriteI2C1(0x6D); IdleI2C1(); MasterWriteI2C1(0x0C); IdleI2C1(); MasterWriteI2C1(0x01); IdleI2C1(); MasterWriteI2C1(0x06); IdleI2C1(); delay(10); StopI2C1(); IdleI2C1(); CGRAM(); //define CGRAM StartI2C1(); MasterWriteI2C1(Slave); IdleI2C1(); MasterWriteI2C1(Comsend); IdleI2C1(); MasterWriteI2C1(0x39); IdleI2C1(); MasterWriteI2C1(0x01); //go back Home IdleI2C1(); StopI2C1(); delay(10); }