If you are able, please Support me on Patreon and/or subscribe to my Youtube channel (instructional videos)
- What does it do?
- PMB Tools' place in "The menagerie"
- Why "The Cuban Mechanics" ?
- Installation
- Issues
PMB Tools is at the heart of several other firmware packages that provide for simple robust and rapid asynchronous IOT development on ESP8266 / ESP32.
Firstly it "smooths out" differences in the hardware of ESP8266 / ESP32 that make writing cross-platform code a lot simpler, faster and easier to debug. This type of thing is usually known as a "Hardware Abstraction Layer" or "HAL"
Secondly it provides a few utility functions of the kind that most programmers collect over the years. They usually include / re-write them at the beginning of every project. I make no claims for any of the functions to be special or clever - they are just my quirky little way of doing things the way I like doing them. They have developed historically and also happen to be called by pretty much every piece of code I write, so - like 'em or not - you gotta have 'em! Finally, there are no doubt many different / better / faster ways of doing some of the tasks: If you think so, then you do them your way and spare me any lessons, please.
Perhaps the quickest explanation for this library is to show the other libraries that depend on it and where it sits in the grand scheme of rapid development of asynchronous multitasking apps on ESP8266 / ESP32:
SEE Installation
Name | Provides | Notes | |
---|---|---|---|
Forked AsyncTCP | "Glue" to LwIP (ESP8266) | Important bugfixes | |
Forked ESPAsyncTCP | "Glue" to LwIP(ESP32) | Missing features added | |
Forked ESPAsyncWebserver | Basis of webUI in H4Plugins | Several major bugfixes | |
PMB Tools | '32/'8266 HAL and utility functions | ||
AardvarkTCP | Simple Large-payload Async TCP | API-compatible with ESPAsyncTCP, seamless TLS/SSL | |
PangolinMQTT | Async MQTT Client | QoS 0/1/2 Fully 3.1.1 compliant. Large payloads | |
ArmadilloHTTP | Async HTTP/S Client | Simple send/callback of large payloads | |
H4 | Scheduler/Async Timers | ||
H4/Plugins | Full Async IOT Firmware | Webserver, MQTT, OTA, NTP, HTTP etc etc |
//
// HAL
//
void _HAL_analogFrequency(uint8_t pin,size_t f=PMB_PWM_DEFAULT);
void _HAL_analogWrite(uint8_t pin, uint32_t value);
void _HAL_attachAnalogPin(uint8_t pin);
void _HAL_feedWatchdog(); // You should NEVER call this - it's here for completenesss only
bool _HAL_isAnalogInput(uint8_t p);
bool _HAL_isAnalogOutput(uint8_t p);
uint32_t _HAL_maxHeapBlock(); // Maxium size of available memory block that can be allocated from heap
size_t _HAL_maxPayloadSize(); // calculated from 1/2 of the above after subtracting PMB_HEAP_SAFETY
string _HAL_uniqueName(const string& prefix); // prefix defaults to "ESP8266" or "ESP32", appends unique H/W chip ID
//
// General purpose / string manipulation
//
// NVP = Name / Value pair refers to a std::map<std::string,std::string>
//
// json refers to "simple json" only: A single, flat hierarchy, anything more complex needs e.g. ArduinoJson lib
//
// While the functions here dela with valid json, they deal only with an extremely limited and specific subset.
// This can save a LOT of space by avoiding external JSON libraries (e.g. ArduinoJson) where you have control over the input
// (e.g. from your own internal webserver(s)) and cane ensure:
// * No arrays
// * no nesting
// * no extraneous whitespace
// * no unquoted values (everything is going to/from std::map<std::string,std::string>
//
// Example:
// {"name":"phil","firmware":"H4","numeric","666"}
//
void dumphex(const uint8_t* mem, size_t len); // pretty formatted hex dump len bytes at address mem
string encodeUTF8(const string &);
string flattenMap(const map<string,string>& m,const string& fs,const string& rs,function<string(const string&)> f=[](const string& s){ return s; });
string flattenMap(const unordered_map<string,string>& m,const string& fs,const string& rs,function<string(const string&)> f=[](const string& s){ return s; });
uint32_t hex2uint(const uint8_t* str); // converts string of x digits to decimal e.g. 02AC becomes 684
string join(const vector<string>& vs,const char* delim="\n"); // flattens/vector/into/string/delimited/by/whatever/u/want
map<string,string> json2nvp(const string& s); /// takes "simple json" and creates name value / pairs inverse of nvp2json
string lowercase(string); // does what it says on the tin
string ltrim(const string& s, const char d=' '); // trims leftmost character(s)
string nvp2json(const map<string,string>& nvp);// flatens NVP into string representation of simple json inverse of json2nvp
string replaceAll(const string& s,const string& f,const string& r); // replace all occurrences of f in s with r
string rtrim(const string& s, const char d=' '); // trims rightmost character(s)
vector<string> split(const string& s, const char* delimiter="\n"); // decomposes "a/b/c..." into {"a","b","c",...}
string stringFromInt(int i,const char* fmt="%d"); // ESP8266 does not have C's itoa etc - this does kinda the same job
bool stringIsAlpha(const string& s); // true if string is entirely "visible ASCII"
bool stringIsNumeric(const string& s); // true if string will covert to a valid integer
string trim(const string& s, const char d=' '); // trims both ends, e.g. returs ltrim(rtrim(x))
string uppercase(string); // DOES WHAT IT SAYS ON THE TINE
string urlencode(const string &s); // pretty standard
Two reasons:
- The functions are small, simple and mostly obvious
- There are dozens of example of usage littered throughout all of the other libraries and example code
Many moons ago I worked for an organisation that expected my small specialist team to work miracles with practically zero resources. It gave rise to quotes such as:
We the unwilling, led by the unknowing
Are doing the impossible for the ungrateful
We have been doing so much for so long with so little
We are now qualified to anything with nothing
Around that time (late 1990s) I read an article about Cuba. During the 1950s it was the playground of rich Americans and the streest of Havan were filled with many imported glitzy space-age US automobiles. Once Fidel Castro came to power, ties with the USA were severed and trade embargoes put in place which made it practically impossible to get spares to keep the gas guzzlers running.
Cuban mechanics therefore reapidly became adept at improvisation, creativity, bodging, repurposing and nigh-on miracle working to prevent their cars from going to the scrapyard. They thus became the "poster boys" for my beleagured team who truly identified with them.
Hence the backdrop is the flag of CUBA and the "skull and crossbones" motif is to evoke our team's sense of being "a bit out there". The skull's beard is taken from an actual photo of Fidel Castro and deliberately badly 'shopped in place, signifying the lash=up nature of a lot of things we were forced to end up doing. The "bones" of the map of Cuba and the spanner then speak for themselves.
I actually printed dozens of sticky labels and we'd surreptitiously place them anywhere we could on any piece of kit we rescued, rebuilt, repaired or stole "re-allocated".
Serious IT doesn't have to be all po-faced. :)
Please see H4 Installer
-
As with all H4 and H4Plugins libraries, please make sure you have read all the relevant documentation relating to the issue and watched any videos on the Youtube channel (instructional videos). Please also subscribe to the channel for notifications of news and updates.
-
If you still think there is a problem, then join the Facebook H4 Support / Discussion group and report the issue briefly there. This is because I visit the group every day, whereas I do not have time to visit 11 github repos every day. Furthermore, it alerts other users to potential problems and allows an initial assessment.
-
If there is a genuine issue then you will be referred to Raising H4/H4Plugins issues after which you are advised to create a full github issue report.
-
Failing to make an initial report in the Facebook H4 Support / Discussion group and simply starting with a github issue, or failing to include all of the information required in Raising H4/H4Plugins issues is likely to result in a long delay before it gets picked up.
(c) 2021 Phil Bowles h4plugins@gmail.com