SIMPLE PROJECT THAT COMMUNICATE WITH SLAVE , TRY TO GET DATA, ANALYZE IT AND PROVIDE OUTPUT. TWO UART INTERFACE, SEMAPHORE, THREAD COMMUNICATION, LCD INTERFACING,PRIORITY BASED THREAD SWITCHING,HEX TO FLOAT CONVERSION
main.cpp
- Committer:
- radhey04ec
- Date:
- 2020-08-09
- Revision:
- 0:7945527e6a18
- Child:
- 1:bdc3ebd4e52b
File content as of revision 0:7945527e6a18:
/* AXF --GLOBAL VALVE BOARD TESTER PROGRAMM CREATED BY : JAYDEEP SHAH RESEARCH & DEVLOPMENT DEPARTMENT -- KEPL DATE : 22 JULY 2020 VERSION : 1.0 -- MBED OPEN VERSION FILE */ /*--------------------------------------------------------------------------*/ /* OUTPUT DATA AVAILABLE ON LCD SCREEN & ON TERMINAL ALSO TERMINAL 9600 BAUD 8-N-1 T TYPE SUGGESTED TERMINAL : COOLTERM & PUTTY If any query /problems --> contact to R&D Dept of KEPL A'bad. Board Turn on Time : 20 to 25 Sec acfetr power */ /*--------------------------------------------------------------------------*/ #include "mbed.h" //MBED LIBRARY #include "TextLCD.h" //LCD LIBRARY /* *************************SEMAPHORE CREATION BINARY********************************* */ Semaphore A(0); #define BUFFER_SIZE 90 //SIZE OF BUFFER -- TO STORE UART DATA TextLCD lcd(PC_0, PC_1, PB_4, PB_5, PB_3, PA_10, TextLCD::LCD20x4); //LCD OBJECT CREATION WITH PANEL SIZE //****************************************************************************** UART SECTION AND FUNCTIONS char rxBuffer[BUFFER_SIZE]; //CREATE CIRCULAR BUFFER -- TO STORE RECEIVE DATA unsigned int bufferReadingIndex=0; //CREATE POINTER TO READ DATA FROM UART AND STORE INTO ARRAY unsigned int i=0; //counter to read data from buffer Array RawSerial UT(PA_0,PA_1); //UART PIN DECLARATION RawSerial pc(USBTX,USBRX); //HOST PC TERMINAL - 9600 BAUD WITH 8-N-1 STTING //NOTE : UT OBJ FOR SLAVE BOARD & pc OBJ FOR TERMINAL //DEFINE Rx Interrupt function --DECLARATION void RxInterrupt(void); //Function that read response data void response(void); //****************************************************************************** UART SECTION & FUNCTIONS void WELCOME_SCREEN(void); //LCD TURN ON DETAILS / POWR ON OR RESTART TIME //void LCD_REFRESH(void); // Thread Function -- to refresh LCD screen------------------------------------------------------TH2 void START_NEW_TEST(void); // Function that call by button press -- new test start volatile bool TEST_FLAG = 0U; //FLAG TO AVOID PUSH BUTTON EFFECT WHEN BOARD ON volatile bool PROCESS_FLAG = 0U; //PROCESS_FLAG -- DURING TESTING ITS ON = 1 volatile uint8_t PCB_COUNTER = 0; //GLOBAL PCB COUNTER //float CURRENT_MEASUREMENT(void); //Thread Function current measurement function that return float value--------------------TH1 float voltage = 0; //Voltage measurement functions //Create Interrupt object -- Pin -- Push button connection********************** DIGITAL I/O SECTION AND INTERRUPT InterruptIn swt(PB_2); //PUSH BUTTON CONNECTED WITH THIS PIN //LED_BUZZER CONNECTION DigitalOut RED_LED(PB_13); // DigitalOut BLUE_LED(PB_14); DigitalOut GREEN_LED(PB_15); DigitalOut BUZZER(PC_8); //BUZZER CONNECT //****************************************************************************** DIGITAL I/O SECTION END //RESULT AND ERROR FUNCTIONS void result(void); void error(uint8_t); //LCD FLAG -- THIS IS FOR RETRIVE DATA FROM ARRAY volatile uint8_t LCD_FLAG = 0; //NEW_TEST_UPDATE_LCD void NEW_TEST_UPDATE_LCD(); //TESTING SCHEDULE FUNCTION void TEST_PROCESS(void); //******************************* VARIABLE TO STORE ADC DATA float current = 0; //Global value float AARAY[10],SUM=0; // THREAD FUNCTIONS************************************************************* THREAD SECTION void CURRENT(void); //TO FIND INPUT DC CURRENT void CURRENT_MEASUREMENT() { while(true) { CURRENT(); //FUNCTION CALL TO MEASURE CURRENT //Thread Yield ThisThread::sleep_for(100); //Thread sleep } } void LCD_REFRESH() { volatile bool v =0; while(true) { v = A.try_acquire(); if(v==1) { lcd.locate(0,3); lcd.printf("Current = %.2f mA",current); lcd.locate(19,3); lcd.printf("ET"); pc.printf("\n Input Current is = %.2f mA",current); ThisThread::sleep_for(150); } } } //****************************************************************************** THREAD SECTION END //CREATE TWO THREAD Thread T1(osPriorityLow),T2; //****************************************************************************** ADC SECTION /* // INA-225 TEXAS INSTRUMENT BOARDS TO AMPLIFY LOW VOLTAGE SIGNAL WITH GAIN 200 //SHUNT RESISTOR = 0.6 Ohm //Vref : 3.3 // I (current) = ((((ADC O/P - Offset)) * 3.3) *200 ) / 0.6) * 1000 mA CLASS --> AnalogIn Object return value between 0 to 1 If 5 V system and you try to read 2.5 V from ADC PIN than OP = 0.5 PLEASE NOTE : MBED USE 3.3 Vref For more information look at thread details */ AnalogIn ANG(PC_3); //Port pin PC_3 last pin for ADC -- Create object /*************************************************************************** UART BUFFER PROBLEMS : FLUSH () NOTE : MBED HAVE NO SUCH TYPE OF FUNCTIONS SO YOU NEED TO CLEAR UART BUFFER BEFORE REPEAT THE PROCEDURE SIMPLE WAY IS READ THE INTERNAL UART BUFFER ***************************************************************************/ //MAKE FUNCTION TO RESET BUFFER DATA AND COUNTER void BUFFER_CLEAR(void); //MAIN FUNCTIONAL AREA************************************************************* //****************FOR NEXT STAGE OF PROJECT bool NEXT = 0U; bool ERROR_FLAG = 0U; int main() { UT.baud(57600); //BAUD RATE SETTING UT.format(8,Serial::None,1); //FORMAT OF UART COMMUNICATION //INTERRUPT ATTACHMENT WHEN RECEIVE DATA --UART INTERRUPT UT.attach(&RxInterrupt,Serial::RxIrq); //PUSH BUTTON INTERRUPT FUNCTION -- PUSH BUTTON INTERRUPT swt.rise(&TEST_PROCESS); //THIS FUNCTION Call when push button press pc.printf("\n STM POWER ON -- DATA INITIALIZATION \n"); pc.printf("\n PROGRAM CREATED BY : R_AND_D DEPT of KEPL \n"); pc.printf("\n Program Version 1.0 \n"); pc.printf("\n Any changes of the program lead toward Board OS Crash or bugs"); pc.printf("\n Permission require before any Hardware / software changes"); pc.printf("\n TRY TO ACCESS main.C CODE......INITIALIZATIO OF RTOS START....."); pc.printf("\n Do not press any Button"); //INITIAL ALL LED OFF pc.printf("\n MAKE ALL LEDS and BUZZER OFF \n"); RED_LED = 0; GREEN_LED = 0; BLUE_LED = 0; BUZZER = 0; WELCOME_SCREEN(); //TO INITIALIZE DATA pc.printf("\n Good Luck !!!!"); pc.printf("\n CURRENT MEASUREMENT UNIT TURNING ON"); T1.start(CURRENT_MEASUREMENT); T2.start(LCD_REFRESH); pc.printf("\n All Thread create succesffully"); wait_ms(500); while(true) { BLUE_LED = 0; START_NEW_TEST(); //This function only work if FLAG SET wait_ms(500); BLUE_LED = 1; } } void RxInterrupt() //if Rx buffer have data --- Interrupt call { //Because of Interrupt -- Ideally no CONTEXT SWITCH if(UT.readable()) //IF data available { rxBuffer[bufferReadingIndex++] = UT.getc(); // read and store into Buffer if(bufferReadingIndex >= BUFFER_SIZE) // If limit cross { bufferReadingIndex =0; // RESET CONTER } } } void response() //FUNCTION TO READ DATA { char rxByte; printf("\n"); //NEED TO STOP CONTEXT SWITCH while(i != bufferReadingIndex) //READ WHILE COMPLETE DATA NOT RECEIVED { rxByte = rxBuffer[i]; //READ DATA ONE BY ONE CHARACTER pc.putc(rxByte); // SEND ON TERMINAL i++; //COUNTER INCREMEN if(i >= BUFFER_SIZE) //IF LIMIT CROSS { i = 0; //RESET COUNTER } } //USE THREAD YIELD FOR UPDATE OTHER THREADS LCD_FLAG = 0; //RESET -- VERSION READ COMPLETED //THREA YIELD } void START_NEW_TEST(void) { if(TEST_FLAG == 1U && PROCESS_FLAG == 0U) { //FLAG MUST BE ZERO NEXT = 0; ERROR_FLAG = 0; RED_LED =0; GREEN_LED =1; PROCESS_FLAG = 1U; //turn test flag on TEST_FLAG =1U; //COUNTER++ PCB_COUNTER++; //NEED TO WAIT 25 ms pc.printf("\n \n \n"); pc.printf("***********************************************************"); pc.printf("AXV 001 PCB NUMBER = %u",PCB_COUNTER); NEW_TEST_UPDATE_LCD(); //THIS FUNCTION IS ONLY FOR DELAY A.release(); //last fucntion to reset flag and display test result wait(0.150); //CLEAR THE BUFFER BEFORE UART COMM //***************TEST - 1 ENTER INTEST MODE AND VERSION READ------------------------------TEST1 BUFFER_CLEAR(); UT.putc('T'); //ENTER IN TEST MODE -- SLAVE BOARD ENTER INTO TEST MODE A.release(); ThisThread::sleep_for(1000); response(); wait(0.10); //FETCHING VERSION NUMBER 01.34 lcd.cls(); lcd.locate(0,0); lcd.printf("VERSION TEST ON"); { uint8_t j=0; char temp_buf[6]; char ver[] = "01.34"; pc.puts("\n FETCHING VERSION FROM IC: "); for(j=13;j<18;j++) { pc.putc(rxBuffer[j]); temp_buf[j-13] = rxBuffer[j]; } temp_buf[5] = '\n'; float value = atof(temp_buf); pc.printf("\n VERSION VALUE IS %f",value); if(value == 1.340000f) { pc.printf("\n Correct Version receive \n"); //PRINT DATA ON LCD lcd.locate(0,1); lcd.printf("VERSION = 1.34"); lcd.printf("VERSION TEST OK"); //GO FOR NEXT TEST NEXT = 1; //READY FOR NEXT TEST A.release(); wait(2); } else { pc.printf("\n Wrong version \n"); //ERROR - STOP TEST ERROR_FLAG = 1; error(1); NEXT = 0; } j = 0; //Clear the buffer data to avoid mistakes } if(NEXT == 1) //**************** RED LED TESTING ********************* { NEXT = 0; lcd.cls(); A.release(); wait(1); BUFFER_CLEAR(); lcd.locate(0,0); lcd.printf("RED LED TEST ON"); pc.printf("\n RED LED TESTING START"); UT.putc('d'); // RED LED OF SLAVE BOARD ON A.release(); wait(1); response(); //Read Response from Slave lcd.locate(0,1); lcd.printf(" "); lcd.printf("RED LED ON ***"); BUFFER_CLEAR(); A.release(); wait(1); lcd.locate(0,1); lcd.printf(" "); lcd.printf("RED LED OFF"); UT.putc('b'); A.release(); wait(1); response(); BUFFER_CLEAR(); pc.printf("RED LED TEST FINISH"); lcd.locate(0,0); lcd.printf(" "); lcd.locate(0,0); lcd.printf("RED LED TEST OK"); NEXT = 1; lcd.locate(0,1); lcd.printf(" "); lcd.locate(0,2); lcd.printf(" "); lcd.locate(0,0); lcd.printf(" "); } if(NEXT == 1)// ********************************* CURRENT TEST { lcd.locate(0,0); BUFFER_CLEAR(); NEXT = 0; pc.printf("\n CURRENT TEST START"); A.release(); wait(1); CURRENT(); lcd.locate(0,1); lcd.printf(" "); lcd.locate(0,2); lcd.printf(" "); lcd.locate(0,0); lcd.printf(" "); lcd.locate(0,1); lcd.printf("CURRENT = %f",current); if(current > 6.5) { error(2); NEXT = 0; ERROR_FLAG = 1; } else { NEXT = 1; ERROR_FLAG = 0; } } if(NEXT == 1)//**********************************CALIBRATION ON { NEXT =0; lcd.locate(0,1); lcd.printf(" "); lcd.locate(0,2); lcd.printf(" "); lcd.locate(0,0); lcd.printf(" "); pc.printf("\n CALIBRATION ON "); lcd.printf("CALIBRATION ON"); lcd.locate(0,1); lcd.printf("PROCESSING"); BUFFER_CLEAR(); UT.putc('c'); A.release(); wait(3); UT.putc('s'); A.release(); wait(1); lcd.locate(0,2); pc.printf("\n CALIBRATION COMPLETE"); lcd.printf("DATA SAVE OK"); NEXT = 1; } if(NEXT ==1)//*****************************BATTERY VOLTAGE TEST { NEXT =0; ERROR_FLAG = 0; lcd.locate(0,1); lcd.printf(" "); lcd.locate(0,2); lcd.printf(" "); lcd.locate(0,0); lcd.printf(" "); lcd.locate(0,0); lcd.printf("Voltage test"); pc.printf("\n VOLTAGE TEST BEGIN"); BUFFER_CLEAR(); UT.putc('A'); A.release(); wait(1); response(); NEXT = 1; } //END OF TEST -- NO NEED TO CHECK NEXT FLAG UT.putc('Q'); wait(1); BUFFER_CLEAR(); if(ERROR_FLAG == 0) { result(); } } //OUTER SIDE BEGIN TEST_FLAG = 0U; PROCESS_FLAG = 0U; GREEN_LED = 0U; RED_LED = 0U; NEXT = 0; ERROR_FLAG =0; } void result() { { wait(3); lcd.cls(); lcd.locate(0,0); lcd.printf("TEST SUCCESSFUL OK"); lcd.locate(0,1); lcd.printf("BOARD TEST - PASS"); lcd.locate(0,2); lcd.printf("PLUG NEW BOARD"); lcd.locate(0,3); lcd.printf("Total Test = %u",PCB_COUNTER); GREEN_LED =1; RED_LED =0; BLUE_LED =0; BUZZER = 1; wait(0.1); BUZZER =0; wait(3); } //AT END OF PROCESS TEST_FLAG = 0U; PROCESS_FLAG = 0U; GREEN_LED = 1U; pc.printf("\n PCB AXV 001 TEST COMPLETED : TEST STATUS - PASS \n"); pc.printf("\n ******************************END OF TEST************************************ \n"); pc.printf("\n \n \n"); pc.printf("\n PLUG NEW BOARD AND PRESS THE BUTTON"); pc.printf("\n \n \n"); wait(5); } void error(uint8_t error_number) { { RED_LED=1; GREEN_LED=0; BLUE_LED=0; BUZZER = 1; wait(1); BUZZER =0; lcd.cls(); lcd.locate(0,0); lcd.printf("Oops ..ERROR"); pc.printf("\n Test Fail "); pc.printf("\n Error -- Contact to HOD"); lcd.locate(0,2); lcd.printf("PLUG NEW BOARD"); lcd.locate(0,3); lcd.printf("Total Test = %u",PCB_COUNTER); if(error_number == 1) { lcd.locate(0,1); lcd.printf("WRONG VERSION"); pc.printf("\n ERROR CODE = 0x1"); pc.printf("\n WRONG VERSION OF SOFTWARE , PLEASE CHECK"); pc.printf("\n POSSIBLE SOLUTION \n"); pc.printf("\n 1) REPROGRAM BOARD 2) CHECK SUPPLY VOLTAGE "); wait(3); } if(error_number == 2) { lcd.locate(0,1); lcd.printf("OVER CURRENT "); pc.printf("\n ERROR CODE = 0X2"); pc.printf("\n OVER CURRENT ERROR"); pc.printf("\n POSSIBLE SOLUTION"); pc.printf("\n TRY TO WASH BOARD AGAIN and RECHECK"); wait(3); } } //AT END OF PROCESS TEST_FLAG = 0U; PROCESS_FLAG = 0U; RED_LED =1; BUZZER = 1; NEXT = 0; //ERROR_FLAG =0; wait(3); BUZZER =0; pc.printf("\n *******************ERROR DESCRIPTION END **************************"); pc.printf("\n ***************************END OF TEST ****************************"); } void WELCOME_SCREEN() { pc.printf("\n"); pc.printf("AXV GOLBAL VALVE TESTER -- FOLLOW THE STEPS \n"); RED_LED = 1; GREEN_LED = 1; BLUE_LED =1; BUZZER = 1; wait(1); BUZZER = 0; //WELCOME SCREEN DATA lcd.cls(); //clear the screen first lcd.printf(" Welcome !!!"); lcd.locate(0,1); lcd.printf("GLOBAL V- TESTER"); lcd.locate(0,2); lcd.printf("POWERED BY : KEPL "); lcd.locate(0,3); lcd.printf("R_AND_D DEPARTMENT"); wait(5); lcd.cls(); lcd.locate(0,0); lcd.printf("Loading..."); lcd.locate(11,0); pc.printf("\n DATA LOADING ....."); pc.printf("\n Veryfying...."); wait_ms(500); lcd.printf("."); lcd.locate(12,0); wait_ms(500); lcd.printf("..."); wait_ms(1000); lcd.locate(13,0); lcd.printf(".."); lcd.locate(0,1); lcd.printf("Veryfied........."); wait_ms(3000); pc.printf("\n LCD COMMUNICATION Successful \n"); lcd.cls(); lcd.locate(0,0); lcd.printf("Done !!!!"); lcd.locate(0,1); lcd.printf("TEST MODE ON"); lcd.locate(0,2); lcd.printf("COUNT = 0"); wait_ms(5000); lcd.cls(); lcd.locate(0,0); BLUE_LED = 1; BUZZER = 1; wait_ms(250); BUZZER = 0; pc.printf("\n SOFTWARE CHECKED & READY TO USE \n"); pc.printf("\n ESD PROTECTION REQUIRE"); pc.printf("\n KEEP YOUR EYES ON TERMINAL OR ON LCD"); pc.printf("\n LED VISUAL AND BUZZER SOUND INDICATION HELPS YOU !!!"); lcd.printf("AXV -T"); lcd.locate(10,0); lcd.printf("Count %u",PCB_COUNTER); } void NEW_TEST_UPDATE_LCD() { GREEN_LED = 1; BLUE_LED = 1; lcd.cls(); lcd.locate(0,0); lcd.printf("TESTING ON..."); pc.printf("\n \n \n"); pc.printf("\n NEW TEST START"); wait(8); //8 SECOND lcd.locate(0,1); lcd.printf("BOARD SCANING.."); pc.printf("\n BOARD SCANNING..."); wait(8); lcd.locate(0,2); lcd.printf("COMMUNICATING..."); pc.printf("\n COMMUNICATION ESTABLISHMENT \n"); wait(5); lcd.printf("READY FOR TEST"); wait(5); lcd.cls(); lcd.locate(0,0); lcd.printf("TEST MODE N 0%u",PCB_COUNTER); pc.printf("TEST MODE ON - COUNT = %u",PCB_COUNTER); A.release(); wait(0.5); } /*Below Function is part of ISR ;so do not write big code inside it If possible than only set and reset flag only Because while servicing Interrupt OS can not schedule or switch other thread or Task In future during updation of version please consider RTOS Management Rule or contact Reserach & development team : JAYDEEP SHAH */ void TEST_PROCESS() //This Function is connected with ISR Of Push_button { if(TEST_FLAG == 0U && PROCESS_FLAG == 0U) { TEST_FLAG = 1U; } else { TEST_FLAG = 0U; } } void CURRENT() { for(int i =0;i <10 ; i++) //Array to make result smoother { AARAY[i] = ANG.read(); //Read the data ThisThread::sleep_for(20); //Thread sleep for make ADC ready for next result SUM = SUM + AARAY[i]; //Store result } float value = (SUM /10); //Finding Average value current = (((((((value)) * 3.3)-0.28)/200)/0.6)*1000); //Finding current current = current + 2.5; // 2.5 is offset (when current is < 50 mA) //pc.printf("\n Current (mA) = %f",current); //Print data on Serial console -- I used CoolTerm SUM = 0; //At the end sum must be zero //A.release(); } void BUFFER_CLEAR() { RxInterrupt(); // To clear serial buffer i = 0U; bufferReadingIndex = 0U; for(int k =0; k<50 ; k++) // ****************CLEAR 50 BYTES BUFFER { rxBuffer[k] = ' '; } }