1+ #include < Taskfun.h>
2+
3+ class Semaphore {
4+ protected:
5+ unsigned _count;
6+
7+ public:
8+ Semaphore (unsigned count)
9+ : _count(count) {}
10+
11+ void Acquire () {
12+ while (1 ) {
13+ noInterrupts ();
14+ if (_count > 0 ) {
15+ --_count;
16+ interrupts ();
17+ break ;
18+ }
19+ interrupts ();
20+ yield ();
21+ }
22+ }
23+
24+ void Release () {
25+ noInterrupts ();
26+ ++_count;
27+ interrupts ();
28+ }
29+ };
30+
31+ class Mutex : public Semaphore {
32+ public:
33+ Mutex ()
34+ : Semaphore(1 ) {}
35+ };
36+
37+ // main program
38+ const int _pins[] = { 9 , 10 , 11 };
39+ const int _numLeds = sizeof (_pins) / sizeof (_pins[0 ]);
40+ const int _buzzerPin = 3 ;
41+
42+ SyncVar<bool > _ledInUse[_numLeds] = { 0 , 0 , 0 };
43+ Semaphore _semaphore (_numLeds);
44+ Mutex _mutex;
45+
46+ const char * _letters[] = { " .-" , " -..." , " -.-." , " -.." , " ." , " ..-." , " --." , " ...." , " .." , " .---" , " -.-" , " .-.." , " --" , " -." , " ---" , " .--." , " --.-" , " .-." , " ..." , " -" , " ..-" , " ...-" , " .--" , " -..-" , " -.--" , " --.." };
47+
48+ template <typename T>
49+ void mutexPrint (T message) {
50+ _mutex.Acquire ();
51+ Serial.print (message);
52+ _mutex.Release ();
53+ }
54+
55+ void blinkMorse (const char * code, int pin) {
56+ auto p = code;
57+ while (*p) {
58+ digitalWrite (pin, HIGH );
59+ auto ms = *p == ' -' ? 300 : 50 ;
60+ delay (ms);
61+ digitalWrite (pin, LOW );
62+ delay (100 );
63+ ++p;
64+ }
65+ }
66+
67+ void blinkMessage (const char * message, int pin) {
68+ auto p = message;
69+ while (*p) {
70+ char c = toupper (*p);
71+ if (c >= ' A' && c <= ' Z' ) {
72+ auto code = _letters[c - ' A' ];
73+ blinkMorse (code, pin);
74+ delay (500 );
75+ }
76+ ++p;
77+ }
78+ }
79+
80+ void processMessage (String message) {
81+ mutexPrint (" Received: " );
82+ mutexPrint (message);
83+
84+ _semaphore.Acquire ();
85+
86+ mutexPrint (" Processing: " );
87+ mutexPrint (message);
88+
89+ for (auto i = 0 ; i < _numLeds; ++i) {
90+ if (!_ledInUse[i]) {
91+ _ledInUse[i] = true ;
92+ blinkMessage (message.c_str (), _pins[i]);
93+ _ledInUse[i] = false ;
94+ break ;
95+ }
96+ }
97+ _semaphore.Release ();
98+ }
99+
100+ void produceTone (int ) {
101+ while (1 ) {
102+ digitalWrite (_buzzerPin, HIGH );
103+ delay (1 );
104+ digitalWrite (_buzzerPin, LOW );
105+ delay (1 );
106+ }
107+ }
108+
109+ void setup () {
110+ Serial.begin (115200 );
111+ Serial.println (" Ready to receive messages..." );
112+ for (auto i = 0 ; i < _numLeds; ++i) {
113+ pinMode (_pins[i], OUTPUT );
114+ }
115+ pinMode (_buzzerPin, OUTPUT );
116+ setupTasks (20 );
117+ runTask (produceTone, 0 , 32 );
118+ }
119+
120+ void loop () {
121+ if (Serial.available ()) {
122+ auto message = Serial.readString ();
123+ runTask (processMessage, message, 96 );
124+ }
125+ }
0 commit comments