This library contains code that allows you to perform dynamic indication on ESP32 under the control of the nanoFramework.
Dynamic indication is basically illustrated in the picture.
Several indicators are connected to a common data bus (a..h) and individually can be switched on one at a time (3 lines down below).
Going through the control signals in a circle with the speed greater then eye can see, you can achieve the illusion that all indicators are ligths at the same time.
Hardware setupFor example, I use 6 NIXIE indicators IN14 and two high voltage decoders 74141 (155ID1). Connected in two groups. Groups are working synchronously to achieve more brightness of indicators.
You can see scematic there:
- High voltage part. Contains Indicators, Decoders and +170 volts power supply. https://easyeda.com/Lolka73/Nixie_clock_hw
- Low voltage part, what contains ESP32 and some other, Not related to this topic parts. https://easyeda.com/Lolka73/Nixie_clock_lw_esp32
The driver consists of two parts:
- Managed code in C#, which is the frontend of the library
- Native C++ code that controls the ports of the GPIO ESSP 2.
The parts are connected through interop mechanism of nanoFramework.
The driver is built as generic as possible. It is necessary to setup:
- Set of pins that will be connected to the data bus of the indicators
- Set of pins of indicator selection pins.
- If the indicators are connected in groups, then the data bus width of one group, else simply whole data bus width.
Then the driver is configured you mast enable indication and indicator switch period.
Simple exampe:
Controller c = new Controller(
new int[] { 27, 26, 25, 33, 32, 5, 18, 19 }, // data bus pins
new int[] { 13, 2, 14 }, // control bus pins
4 // Data bits pre one indicator group 74141 input data bits count
);
// setup period for group switching 5ms for me is ok (no flicker)
c.UpdatePeriod_us = 5000;
// Start controller to display data on indicators
c.Enabled = true;
But how about the content?The connection scheme of indicators can be very confusing, so the library only works with raw data. The user must encode data for proper display on indicators.
Raw data is transferred to the library as a unit[] array, each element of the array corresponds to it's own indicator. The value in the array element will be set to the data bus of the indicators "as-is", if the data bus is four bits wide, then the lower 4 bits of the array element will be used.
// it displays "01 23 45" for may schematic
c.SetData(new uint[] { 3, 2, 4, 1, 8, 13 });
More detailsIntertop in nanoFramwork has a number of limitations. One of them is the difficult access to the fields of the managed C# object of the Native C++ code.
The purpose of this library is high performance, so it was decided to assign the periodic work of updating the data and control bus to a native code, the update events are provided by a timer from the ESP-IDF SDK. Once the update events are bypassing the nanoframework virtual machine, it is necessary to store the driver state, but at the same time it needs to have a link with the managed object, which is the frontend to possibility of control.
The NativeState template class is used to store the native driver state (such of data buffer), std::map is used to connect to it's owner - C# object.
Thus, when creating a new driver object, another native object is created "under it", and each time the native method is called, mapping between the managed and native objects is performed.
// Controller.h
struct Controller
{
...
private:
// C# object pointer to C++ object map
static std::map<CLR_RT_HeapBlock *, NativeState<selector_t, display_policy_t>> stateMap;
};
// Controller.cpp
void Controller::NativeSetData(CLR_RT_HeapBlock *pMngObj, CLR_RT_TypedArray_UINT32 ¶m0, HRESULT &hr)
{
// perform mapping CLR_RT_HeapBlock* -> NativeState<...>
auto pNativeThis = stateMap.find(pMngObj);
if (pNativeThis == stateMap.end())
{
// Not found! Error, native object was destroyed
hr = CLR_E_OBJECT_DISPOSED;
return;
}
// Call native method itself
pNativeThis->second.setData(param0);
}
Comments
Please log in or sign up to comment.