Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* 00002 Copyright (c) 2018 - Moran ZALTSMAN 00003 00004 This program is free software: you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation, either version 3 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program. If not, see <https://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include "mbed.h" 00019 #include "mbed_mem_trace.h" 00020 /*#include "hal/pinmap.h"*/ 00021 #include "DebounceIn.h" 00022 00023 // a Polling-based (IRQ-less) Edge-Detection Mechanism - Using DebounceIn Class & mBed-OS Thread(s) : 00024 00025 // [ Note : Shared-Resource (e.g. : PWMOut, BusOut) Are At Least Thread-Safe ( See : https://docs.mbed.com/docs/mbed-os-handbook/en/latest/concepts/thread_safety/ ) ] 00026 00027 DebounceIn btn_1(PA_11, PullUp), btn_2(PA_12, PullUp); // Inverted Logic : On -> "0", Off -> "1" 00028 00029 PwmOut pwm_out_1(PA_8); 00030 00031 BusOut bus_out_1(PA_15, PB_3, PB_4, PB_5); // a 4-bit Bus - For a 4 LED Status-Display Setup 00032 00033 00034 class PwmOut_Elevator 00035 { 00036 public: 00037 00038 PwmOut_Elevator(DebounceIn *debounce_in, PwmOut *pwm_out, float step) { _debounce_in = debounce_in; _pwm_out = pwm_out; _step = step; }; 00039 00040 void PwmOut_Elevator_Operator() /* To Be Run Inside a Thread */ 00041 { 00042 while (1) 00043 { 00044 ThisThread::sleep_for((_debounce_in->get_debounce_us() / 1000) - 1); // Sleep for a Single (1) DebounceIn Sampling-Period 00045 00046 if ((_debounce_in->get_edge_direction() == 0) && (_debounce_in->get_edge_direction_acted_upon() == 0)) 00047 { 00048 if ((_pwm_out->read() + _step) >= 0.65f) { _pwm_out->write(_pwm_out->read() + _step); } 00049 else { _pwm_out->write(0.65f); } // <- a Fail-Safe Default 00050 00051 _debounce_in->set_edge_direction_acted_upon(); 00052 } 00053 } 00054 } 00055 00056 protected: 00057 00058 DebounceIn *_debounce_in; 00059 PwmOut *_pwm_out; 00060 float _step; 00061 00062 }; // class PwmOut_Elevator - Ends 00063 00064 00065 class Display 00066 { 00067 public: 00068 00069 Display(BusOut *bus_out, PwmOut *pwm_out) { _bus_out = bus_out; _pwm_out = pwm_out; }; 00070 00071 void Display_Operator(void) /* To Be Run Inside a Thread */ 00072 { 00073 while (1) 00074 { 00075 ThisThread::sleep_for(10); // 10ms -> a Projected 100-Hz Update Rate 00076 00077 _bus_out->write( (uint8_t ((_pwm_out->read() - 0.65f)/0.05f)) + 1 ); // (65% -> 1) .. (100% -> 8), 5% Step 00078 } 00079 } 00080 00081 protected: 00082 00083 PwmOut *_pwm_out; 00084 BusOut *_bus_out; 00085 00086 }; // class Display - Ends 00087 00088 00089 PwmOut_Elevator btn_1_pwmout_elevator(&btn_1, &pwm_out_1, 0.05f), btn_2_pwmout_elevator(&btn_2, &pwm_out_1, -0.05f); 00090 00091 Display display_1(&bus_out_1, &pwm_out_1); 00092 00093 00094 // for Debugging 00095 Semaphore smph_debug_output(1, 1); // (a Binary Semaphore - e.g. : Effectively a Mutex) 00096 00097 Serial port_serial_1(PA_9, PA_10); 00098 00099 class Debug 00100 { 00101 public: 00102 00103 Debug(Serial *port_serial) { _serial = port_serial; } 00104 00105 void Debug_Output_Mem_Stats(void) /* To Be Run Inside a Thread */ 00106 { 00107 // allocate enough room for every thread's stack statistics 00108 // int8_t cnt = osThreadGetCount(); 00109 // mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t)); 00110 int8_t cnt; 00111 00112 _serial->printf("Debug::Debug_Output_Mem_Stats() : Hello ! :)\r\n\r\n"); 00113 00114 while (1) 00115 { 00116 smph_debug_output.wait(); 00117 00118 cnt = osThreadGetCount(); 00119 00120 // mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t)); 00121 mbed_stats_stack_t *stats = new mbed_stats_stack_t[cnt]; 00122 00123 cnt = mbed_stats_stack_get_each(stats, cnt); 00124 00125 for (int8_t i = 0; i < cnt; i++) { 00126 _serial->printf("Debug::Debug_Output_Mem_Stats(): Thread: 0x%lX, Stack size: %lu / %lu\r\n", stats[i].thread_id, stats[i].max_size, stats[i].reserved_size); 00127 } 00128 00129 // free(stats); 00130 delete stats; 00131 00132 // Grab the heap statistics 00133 mbed_stats_heap_t heap_stats; 00134 mbed_stats_heap_get(&heap_stats); 00135 _serial->printf("Debug::Debug_Output_Mem_Stats(): Heap size: %lu / %lu bytes\r\n\r\n", heap_stats.current_size, heap_stats.reserved_size); 00136 00137 smph_debug_output.release(); 00138 00139 ThisThread::sleep_for(250); 00140 } 00141 00142 } 00143 00144 void Debug_Output_General(void) /* To Be Run Inside a Thread */ 00145 { 00146 _serial->printf("Debug::Debug_Output_General() : Hello ! :)\r\n\r\n"); 00147 00148 while (1) 00149 { 00150 smph_debug_output.wait(); 00151 00152 _serial->printf("Debug::Debug_Output_General() : 'btn_1' Current Value = %d\r\n", btn_1.read()); 00153 _serial->printf("Debug::Debug_Output_General() : 'btn_1/edge_direction' Current Value = %d\r\n", btn_1.get_edge_direction()); 00154 _serial->printf("Debug::Debug_Output_General() : 'btn_1/edge_direction_acted_upon' Current Value = %d\r\n", btn_1.get_edge_direction_acted_upon()); 00155 _serial->printf("Debug::Debug_Output_General() : 'btn_2' Current Value = %d\r\n", btn_2.read()); 00156 _serial->printf("Debug::Debug_Output_General() : 'btn_2/edge_direction' Current Value = %d\r\n", btn_2.get_edge_direction()); 00157 _serial->printf("Debug::Debug_Output_General() : 'btn_2/edge_direction_acted_upon' Current Value = %d\r\n", btn_2.get_edge_direction_acted_upon()); 00158 _serial->printf("Debug::Debug_Output_General() : 'pwm_out_1' Current Value = %f\r\n", pwm_out_1.read()); 00159 _serial->printf("Debug::Debug_Output_General() : 'bus_out_1' Current Value = %d\r\n\r\n", bus_out_1.read()); 00160 00161 smph_debug_output.release(); 00162 00163 ThisThread::sleep_for(250); 00164 } 00165 } 00166 00167 protected: 00168 00169 Serial *_serial; 00170 00171 }; // class Debug - Ends 00172 00173 Debug debug_1(&port_serial_1); 00174 /// 00175 00176 Thread btn_1_thr(osPriorityNormal, 240), btn_2_thr(osPriorityNormal, 240), display_thr(osPriorityNormal, 240), debug_general_thr(osPriorityNormal, 640), debug_mem_stats_thr(osPriorityNormal, 640); 00177 00178 00179 int main() 00180 { 00181 mbed_mem_trace_set_callback(mbed_mem_trace_default_callback); 00182 00183 // Set PWM 00184 pwm_out_1.period_us(40); // 25 kHz Period 00185 pwm_out_1.write(0.65f); // 65% Duty-Cycle (65% Fan Speed : a Safe Default) 00186 /// 00187 00188 debug_general_thr.start(callback(&debug_1, &Debug::Debug_Output_General)); 00189 00190 port_serial_1.printf("main(): 'debug_general_thr' Started.\r\n"); 00191 00192 debug_mem_stats_thr.start(callback(&debug_1, &Debug::Debug_Output_Mem_Stats)); 00193 00194 port_serial_1.printf("main(): 'debug_mem_stats_thr' Started.\r\n"); 00195 00196 port_serial_1.printf("main(): Going To Sleep For a %dms\r\n", ((btn_1.get_debounce_us()*btn_1.get_samples()/1000)+1)); 00197 00198 ThisThread::sleep_for((btn_1.get_debounce_us()*btn_1.get_samples()/1000)+1); // Sleep for 251ms - To Get Initial Stable Input-Values of Buttons via Their DebounceIn Instances 00199 00200 btn_1_thr.start(callback(&btn_1_pwmout_elevator, &PwmOut_Elevator::PwmOut_Elevator_Operator)); 00201 00202 port_serial_1.printf("main(): 'btn_1_thr' Started.\r\n"); 00203 00204 ThisThread::sleep_for(100); 00205 00206 btn_2_thr.start(callback(&btn_2_pwmout_elevator, &PwmOut_Elevator::PwmOut_Elevator_Operator)); 00207 00208 port_serial_1.printf("main(): 'btn_2_thr' Started.\r\n"); 00209 00210 ThisThread::sleep_for(100); 00211 00212 display_thr.start(callback(&display_1, &Display::Display_Operator)); 00213 00214 port_serial_1.printf("main(): 'display_thr' Started.\r\n"); 00215 00216 ThisThread::sleep_for(osWaitForever); 00217 }
Generated on Wed Jul 13 2022 08:13:48 by
1.7.2