// file: pico.c // author: KLL /* * v01 test ADC A0 A1 A2 A4 (cpu temp) JOB1 * v02 make the counter / + timer / basic loop * v03 i did it again: the Chart Line on A0 A1 JOB2 * v04 menu text and options * v05 set RTC time on operator input 'T' */ /* * CMakeLists.txt // _____________________________ please make this file in your 'project' directory with following content: cmake_minimum_required(VERSION 3.12) #include(pico_sdk_import.cmake) include(~/pico/pico-sdk/external/pico_sdk_import.cmake) project(project) pico_sdk_init() # cross compile a c++ code for the PICO add_executable(pico pico.c) # Pull in our pico_stdlib which pulls in commonly used features target_link_libraries(pico pico_stdlib hardware_adc hardware_rtc) # enable usb output, disable uart output pico_enable_stdio_usb(pico 1) pico_enable_stdio_uart(pico 0) # create map/bin/hex/uf2 file etc. pico_add_extra_outputs(pico) */ /* ADC hardware test * a GP 29 A3 does not exist on PICO board * test pin 38 GND to GP26 27 28 as pin 31 32 34 as A0,A1,A2 show 0.0xx V * test pin 36 3.3V to GP26 27 28 as pin 31 32 34 show 3.299 V * temperature as A4? show about 24 degC room temp */ #include #include #include "pico/stdlib.h" #include "pico/time.h" #include "pico/util/datetime.h" #include "hardware/gpio.h" #include "hardware/adc.h" #include "hardware/rtc.h" #include "hardware/timer.h" // DIAG print diagnostic info bool DIAG = true;//false; //true; //_____________ code testing bool DIAGM = false; //true; //___________________ Mega Loops print // LED const uint LED_PIN = 25; bool LED_stat = false; // ADC const float conversion_factor = 3.3f / (1 << 12); // 12-bit conversion, assume max value == ADC_VREF == 3.3 V const float conversion_line = 101.0f / (1 << 12); // 12-bit conversion, assume max value == ADC_VREF == 3.3 V make it 101 character for Chart Line // RTC char datetime_buf[256]; char *datetime_str = &datetime_buf[0]; datetime_t t = { // Start .year = 2021, .month = 03, .day = 03, .dotw = 3, // 0 is Sunday, so 6 is Saturday .hour = 00, .min = 00, .sec = 00 }; int setup() { stdio_init_all(); //___________________________________________ LED related gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); //___________________________________________ ADC related adc_init(); adc_gpio_init(26); //________________________ Make sure GPIO is high-impedance, no pullups etc adc_gpio_init(27); adc_gpio_init(28); adc_set_temp_sensor_enabled(true); //___________________________________________ RTC related rtc_init(); //_______________________________ Start the RTC rtc_set_datetime(&t); //___________________________________________ end setup printf("\ni am PICO\n"); //__________________ i never see that ? } int LED_toggle(bool printit) { LED_stat = !LED_stat; //_____________________ toggle if ( LED_stat ) { gpio_put(LED_PIN, 1); if ( printit ) { printf(" LED ON \n"); } } else { gpio_put(LED_PIN, 0); if ( printit ) { printf(" LED OFF\n"); } } } int get_Ains() { adc_select_input(0); // Select ADC input 0 (GPIO26) pin 31 float A0 = adc_read() * conversion_factor; adc_select_input(1); // Select ADC input 1 (GPIO27) pin 32 float A1 = adc_read() * conversion_factor; adc_select_input(2); // Select ADC input 2 (GPIO28) pin 34 float A2 = adc_read() * conversion_factor; // A3 on GP29 is internal wired on the board and used by cpu ADC code? adc_select_input(4); // Select ADC input ? T = 27 - (ADC_Voltage - 0.706)/0.001721 float A4 = 27.0 - ( adc_read() * conversion_factor - 0.706)/0.001721; printf("A0, %.3f ,A1, %.3f ,A2, %.3f, V; A4, %.1f , degC cpu temp,\n", A0, A1, A2, A4); } int make_chart() { char chartline[102] = "!_________!_________!_________!_________!_________!_________!_________!_________!_________!_________!"; adc_select_input(0); // Select ADC input 0 (GPIO26) pin 31 int cpos_A0 = (int)(adc_read() * conversion_line); adc_select_input(1); // Select ADC input 1 (GPIO27) pin 32 int cpos_A1 = (int)(adc_read() * conversion_line); chartline[cpos_A0]='0'; chartline[cpos_A1]='1'; //printf("%s ,%d,%d\n", chartline,cpos_A0,cpos_A1); // diag print cpos printf("%s\n", chartline); } int get_RTC(bool printit) { //___________________ print date time no tailing lf rtc_get_datetime(&t); datetime_to_str(datetime_str, sizeof(datetime_buf), &t); if ( printit ) { printf("%s ", datetime_str); } //_ no lf } int ask_number_uint(char *question) { uint32_t in_num=0; printf("%s ", question); scanf("%d",&in_num); // you type blind ?no echo? but see the result printed later printf("%d \n",in_num); // echo and new line return in_num; } int set_RTC(bool printit ) { //__________________ ask operator to give numbers to set RTC printf("we wait until you answer all questions about new RTC time setting, this will block the control loop\n"); int in_year = ask_number_uint("year? like 2021: and use [enter]"); int in_month = ask_number_uint("month? like 1 .. 12: and use [enter]"); int in_day = ask_number_uint("day? like 1 .. 31: and use [enter]"); int in_dotw = ask_number_uint("day of week? like 0 is Sunday, so 6 is Saturday: and use [enter]"); int in_hour = ask_number_uint("hour? like 0 .. 23: and use [enter]"); int in_min = ask_number_uint("minute? like 0 .. 59: and use [enter]"); int in_sec = ask_number_uint("seconds? like 0 .. 59: and use [enter]"); printf("we see: %d.%d.%d %d %d:%d:%d \n",in_year,in_month,in_day,in_dotw,in_hour,in_min,in_sec); datetime_t t_new = { // Start .year = in_year, .month = in_month, .day = in_day, .dotw = in_dotw, // 0 is Sunday, so 6 is Saturday .hour = in_hour, .min = in_min, .sec = in_sec }; rtc_set_datetime(&t_new); // ? can i know if that was accepted somehow ? sleep_ms(1000); //___________________________ need wait for update? how long ? get_RTC(true); //____________________________ to show new time } uint64_t millis() { uint64_t micros = time_us_64(); uint64_t thismillis = micros/1000; //if ( DIAG ) { printf("micros %" PRIu64 " , millis %" PRIu64 "\n",micros, thismillis); } return thismillis; } //_______________________________________________ MENU int menu() { printf("\n"); printf("_______________________________________\n"); printf("| KLL engineering |\n"); printf("| Raspberry Pi PICO serial menu |\n"); printf("|_____________________________________|\n"); printf("| |\n"); printf("| 0 reset all jobs |\n"); printf("| 1 job1 A0 A1 A2 A4 print |\n"); printf("| 2 job2 A0 A1 Chart Line |\n"); printf("| |\n"); printf("| |\n"); printf("| |\n"); printf("| |\n"); printf("| |\n"); printf("|_____________________________________|\n"); printf("| [space] or [?] this menu |\n"); printf("| d diagnostic toggle |\n"); printf("| l megaloop info toggle |\n"); printf("| T set Time |\n"); printf("| |\n"); printf("|_____________________________________|\n"); printf("select:\n"); } // Multi Tasking JOB counter structure uint32_t main_count = 0; uint32_t main_limit = 1000000; //________________ count to M // PICO about 3 times per sec ? 12 times faster as Arduino UNO ? uint32_t main_Mloops = 0; bool menu_init = true; //________________________ after first Mloop print menu once uint32_t ser0_count = 0; uint32_t ser0_limit = 1000000; // only after .. main loops check on serial USB OPERATOR input int c_usb; //____________________________________ operator menu input char bool job1_enable = false;//true; uint32_t job1_count = 0; uint32_t job1_limit = 5000; // only after 5000 main loops check millis uint64_t job1_lastmsec = 0; uint64_t job1_setmsec = 5000; // 5 sec bool job2_enable = true; uint32_t job2_count = 0; uint32_t job2_limit = 200000; // do only after ... main loops int job0() { //__________________________________ JOB0 ( after 1.000.000 loops ) get_RTC(DIAGM); //___________________________ show time LED_toggle(DIAGM); //________________________ LED toggle if ( DIAGM ) { printf("Mloops %d \n",main_Mloops); } // show Mloops counter if ( menu_init) { menu(); menu_init = false; //____________________ not again } } int ser0() { //__________________________________ check for operator input after counter / do not check serial buffer every loop ser0_count += 1; //__________________________ cycles if ( ser0_count >= ser0_limit ) { ser0_count = 0; //_______________________ reset if (false) { printf("check USB input"); } c_usb = getchar_timeout_us(0); //________ OPERATION switch(c_usb) { case ' ': menu(); //_______________________ print MENU on [space] input break; case '?': menu(); break; case '0': //_________________________ ALL OFF job1_enable = false; job2_enable = false; printf("all jobs OFF, use [ ] or [?] for menu"); break; case '1': //_________________________ toggle JOB1 job1_enable = !job1_enable; break; case '2': //_________________________ toggle JOB2 job2_enable = !job2_enable; break; case 'd': //_________________________ print debug info DIAG = !DIAG; break; case 'l': //_________________________ print MEGA LOOP timing DIAGM = !DIAGM; break; case 'T': //_________________________ ask for numbers to set RTC time set_RTC(true); break; default: ;//printf("what was that?"); } } } int job1() { //__________________________________ JOB1 USER DEFINED JOB get_RTC(DIAG); //____________________________ show time //printf(" JOB1 "); get_Ains(); //_______________________________ THE JOB } int job2() { //__________________________________ JOB2 USER DEFINED JOB get_RTC(DIAG); //____________________________ show time //printf(" JOB2 "); make_chart(); //_____________________________ THE JOB } int job_check() { //_____________________________ basic counter loop main_count += 1; //__________________________ cycles if ( main_count >= main_limit ) { main_count = 0; //_______________________ reset main_Mloops += 1; job0(); } ser0(); //___________________________________ check USB input with its own counter if ( job1_enable ){ job1_count += 1; //______________________ JOB1 ( this is a time based JOB ) if ( job1_count >= job1_limit ) { job1_count = 0; //___________________ reset if ( job1_lastmsec + job1_setmsec <= millis() ) { job1_lastmsec += job1_setmsec; // remember this time in milli seconds since boot job1(); //job1_enable = false; //________ use for ONE SHOT JOBS } } } if ( job2_enable ){ job2_count += 1; //______________________ JOB2 ( this is a counter based JOB ) if ( job2_count >= job2_limit ) { job2_count = 0; //___________________ reset job2(); //job2_enable = false; //____________ use for ONE SHOT JOBS } } } int main() { setup(); //__________________________________ SETUP while (1) { //_______________________________ LOOP job_check(); } } // ______________________________________________ END