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.
Diff: StatusIndicator.h
- Revision:
- 6:02df5c1108f1
- Parent:
- 2:aa9a1377aa0d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/StatusIndicator.h Thu Apr 09 22:40:13 2020 +0000 @@ -0,0 +1,292 @@ +/* mbedBug @version 0.x +@link https://github.com/KabukiStarship/mbedBug.git +@file /StatusIndicator.h +@author Cale McCollough <https://cale-mccollough.github.io> +@license Copyright 2016-20 (C) Kabuki Starship <kabukistarship.com>; all rights +reserved (R). This Source Code Form is subject to the terms of the Mozilla +Public License, v. 2.0. If a copy of the MPL was not distributed with this file, +You can obtain one at <https://mozilla.org/MPL/2.0/>. */ +#ifndef _mbedBug_StatusLED_header +#define _mbedBug_StatusLED_header +#define _Debug 0 //< Use this flag to turn this library into a debug example program. @see mbedBug.cpp:int main () +#include <mbedBug.h> +#define _CreateStatusLED \ +static StatusIndicator<0,1> Status (GREEN_LED);\ + +#define Assert(Statement, Message) {\ + if (!(Statement)) {\ + printf("Assert: %s\r\n%s, line %d\r\n", #Message, __FILE__, __LINE__)\ + Status.HandleAssert ()\ + while (true)\ + }\ +} + +namespace mbedBug { + +/* Outputs the firmware Status using an LED/buzzer/etc. +This class works by using strings with ASCII Mores Code. Each char in a +represents a pulse split into 4 lengths. + +| Frame | ASCII | Index | Duty Cycle | +|:-----:|:-----:|:-----:|:----------:| +| Off | ' ' | <= 44 | 0% | +| Long | '-' | 45 | 1/3 | +| Short | '.' | 46 | 1/3 | +| On | '_' | >= 47 | 100% | + +Off could be any value less than 44, and On could be any value greater than +47, but ASCII space (' ') and Period ('.') are used by convention because +they look like the pulse widths. + +## Terminology +* Frame - Each character in a char Sequence represents 3 timer interrupts. +* Pattern - A null-terminated string of frames. +* Sequence - A null-terminated string of const char*. + +@code +StatusIndicator<0, 1> stausLED (); //< Use <0, 1> if you're LED is active low. +StatusIndicator<1, 0> stausLED (LED_2); //< Use <0, 1> if you're LED is active high. + +const char* ExamplePattern[] = { + "... ", //< Blinks fast three times in a row. + "...---... ", //< SOS in Mores Code. + "____ ", //< Slowly blinks on and off. + 0 //< Must have null-termination pointer. +}; + +statusLED.SetPattern (exapmlePattern, 1.5f); + +@endcode +*/ +template <int On, int Off> +class StatusIndicator { + public: + + char Count, //< Counter counts from from 1-3. + Period; //< The current Period char. + + float Frequency; //< The Period length + + const char** Sequence; //< Null-terminated string of pointers. + + const char* Pattern, //< The current string in the Sequence. + * Cursor; //< The current char in the current string. + + DigitalOut Pin; //< Red LED on the mbed board. + + Ticker Blinker; //< Ticker for blinking the LEDs. + + static const float FrequencyDefault = 0.5f, //< Default Frequency in hertz. + FrequencyMin = 0.01f, //< Min Frequency in hertz. + FrequencyMax = 2.0f; //< Max Frequency in hertz. + + typedef enum { + Off = 0, + Short = 63, + Long = 127, + On = 255 + } Pulse; + + /* Simple constructor. */ + StatusIndicator (PinName LEDPin = LED1, float Frequency = FrequencyDefault): + Count (0), + Period (0), + Sequence (0), + Pattern (0), + Cursor (0), + Frequency (Frequency), + Pin (LEDPin, Off) { + /// Nothing to do here. + } + + /* Sets the light blinking Sequence. */ + void SetSequence (char** SequenceNew) { + if (!SequenceNew) { + Sequence = 0; + StopBlinking (); + return; + } + + const char* TempString = Sequence[0]; + + if (TempString == 0 || TempString[0] == 0) { + DPrintf("\r\n\nError: First Sequence and first char can't be null." + "\r\n\n"); + return; + } + Sequence = SequenceNew; + Pattern = SequenceNew[0]; + Cursor = Pattern; + CurrentByte = *Cursor; + Update (); + } + + /* Turns off the Blinker. */ + void TurnOff () { + Pin = Off; + } + + /* Turns on the Blinker. */ + void TurnOn () { + Color = ColorA; + Update (); + } + + /* Starts flashing the SOS Sequence. */ + void FlashSOS () { + Sequence = SoSPattern (); + Cursor = Sequence[0]; + Cursor = *Cursor; + Period = *Cursor; + } + + /* Starts blinking. */ + void StartBlinking () { + const char* _pattern = Sequence[0]; + Pattern = _pattern; + Cursor = _pattern; + Period = *_pattern; + + Blinker.attach (this, &StatusIndicator::blink, Frequency / 4); + Update (); + } + + /* Stops blinking and turns off the LED. */ + void StopBlinking () { + TurnOff (); + Blinker.detach (); + Pin = Off; + Update (); + } + + /* Sets the blink Frequency. */ + void FrequencySet (float Value) { + Frequency = Value; + Blinker.attach (this, &StatusIndicator::Blink, Value); + } + + /* Handler for the Assert macro. */ + void HandleAssert () { + SetPattern (SoSPattern ()); + } + + /* Pattern blinks three times in a row. */ + const char** Blink3TimesPattern () { + static const char** Sequence = { "... ", 0 }; + return &Sequence; + } + + /* Standard blink Sequence. */ + const char** SlowBlinkPattern () { + static const char** Sequence = { "__ ", 0 }; + return &Sequence; + } + + /* Standard blink Sequence. */ + const char** FastBlinkPattern () { + static const char** Sequence = { "_ ", 0 }; + return &Sequence; + } + + /* Standard SOS Sequence. */ + const char** SoSPattern () { + static const char** Sequence = { "...---... ", 0 }; + return &Sequence; + } + + /* Returns the next char in the Sequence. */ + inline char GetNextPeriod () { + /// We've already checked that the Sequence and Cursor and not null. + + char period_temp = *(++Cursor); + + if (period_temp == 0) { + const char* temp_pattern = *(Pattern + sizeof (const char*)); + + if (!temp_pattern) { + const char* _cursor = Sequence[0]; + Cursor = Pattern = _cursor; + return *_cursor; + } + Pattern = temp_pattern; + return *temp_pattern; //< We don't particularly care if the Period is '\0'. + } + + return period_temp; + } + + /* Updates the Status LED. */ + inline void Update () { + const char* period_temp = Period; + if (!Sequence || !period_temp) return; + + if (Count == 0) { //< Beginning of cycle Period. + char _period = GetNextPeriod (); + Period = _period; + Count = 1; + if (_period < '-') { + Pin = Off; + return; + } + Pin = On; + return; + } + else if (Count == 1) { //< 1/3 duty cycle. + Count = 2; + if (Period == '.') { + Pin = Off; + return; + } + return; + } + /// 2/3 duty cycle. + Count = 0; + if (Period > '.') //< Leave the LED on + return; + Pin = Off; + } +}; +} + +// _D_e_m_o_____________________________________________________________________ + +#if 0 //< Set to non-zero to run this demo. + +using namespace mbedBug; + +StatusIndicator Status (); +InterruptIn switch3 (SW3); + +const char* ExamplePattern[] = { + "... ", //< Blinks fast three times in a row. + "...---... ", //< SOS in Mores Code. + "____ ", //< Slowly blinks on and off. + 0 //< Pattern must have null-term pointer. +}; +/* Interrupt handler for SW2. */ +void SwitchIRQHandler () { + static bool ExamplePatterMode = true; + + if (ExamplePatterMode) { + Status.SetPattern (ExamplePattern); + Status.StartBlinking (); + ExamplePatterMode = false; + } + else { + Status.SetPattern(Status.SOSPattern ())); + ExamplePatterMode = true; + } +} + +int main() { + printf ("\r\n\nTesting mbed Utils.\r\n\n"); + PrintLine (); + + switch3.rise (&SwitchIRQHandler); + //Status.StartBlinking () + + while (true); +} + +#endif //< Demo +#endif