Firstly, high resolution pictures, because there aren’t any online that I could find and without these it’s very hard to figure out how the board is routed:
Above you can see the Ethernet PHY chip, the RS485 serial chip, and the 12v buck converter to 5v.
The board has very good build quality. Soldering and traces are clean, every input and output is buffered, and a very wide range of voltages is therefore tolerated. The Hongfa 16A relays are considerably better quality than the cheap Chinese 10A claimed relays normally in tinkerer boards and I think I’d trust them with 230V AC. I tried out the relays, the digital i/o both as input and output, and the analogue inputs. Analogue inputs looked very stable when fed a potentiometer, no noise, drift nor random walk, and the full 10-bit range was clearly present with equal resolution at the extreme low and high as in the middle (unlike ESP8266 for example). Ethernet came up and worked without issue. I plugged a cheap 12v AC adapter into it, found no issue. 5v output from the board measured at 5.1v, which is fine. I haven’t tested the RS485 port nor UARTs, but I intend to do so soon. The USB socket, incidentally, appears as a serial port to your computer. I don’t think you can use it for anything other than with the dScript IDE, which seems rather unfortunate.
All in all, I think the hardware great value for €75. This board is maybe 20% more expensive than the cheapest ethernet relay boards off Aliexpress, but it’s an absolute world of difference in build quality. I’d trust this to switch an immersion, which I don’t think a good idea at all with any of the typical relay HATs for the Raspberry Pi.
Regarding the software side of things, I didn’t get too much time to play with that this weekend – you’ll need to wait until next weekend for me to have a proper go off the proprietary programming language. On the one hand, this isn’t some dumb board with no locally programmable logic blindly obeying commands hitting its Ethernet port – it is quite programmable e.g. if five conditions are satisfied, connect to another computer and write some arbitrary payload to that socket, or accumulate statistics, analyse them and email a summary every day. On the other hand, its proprietary dScript programming language is a weird mix of features and capabilities, some big fat ones like the ability to send email, yet no time keeping better than a second unless you implement your own.
However I did write this little dScript program in the dScript IDE to test the board:
const STEPS 16 const DELAY 1000 int32 on_count int32 off_count int32 on_max int32 off_max thread main(const) int32 N off_max = STEPS off_count = 1 threadstart Timer1 threadsleep DELAY for N = 1 to STEPS - 1 threadsleep DELAY off_max = N on_max = STEPS - N if on_count == 0 and off_count == 0 then on_count = 1 endif next endthread thread Timer1(1) if on_count > 0 then on_count -= 1 if on_count == 0 then IO1 = off off_count = off_max threadsuspend endif endif if off_count > 0 then off_count -= 1 if off_count == 0 then IO1 = on on_count = on_max threadsuspend endif endif endthread
Which yields this on a RGB LED I hooked up to digital i/o 1 which uses PWM to reduce the brightness of the LED from 100% to 6.25% in even steps over sixteen seconds:
The video makes it look far worse than it is to the human eye, where any PWM flicker isn’t noticeable until the dimmest setting, and even then, only from the side of the eye’s focal point. The PWM flicker is due to the 16 ms duty cycle, which is only 62Hz, barely any better than a cheap diode based LED AC bulb flickering at 50Hz. But it’s the best possible on a millisecond granularity timing system, which is the finest timer granularity dScript exposes. This is unfortunate as even though dScript is an interpreted language running on an 80Mhz CPU, it should be able to pulse an i/o at 50Khz in software if the board isn’t doing much else.
In case you were wondering, yes the PIC32MX has hardware PWM. However dScript doesn’t expose that, and when I asked Devantech support if it could, I was told that the PWM capable pins are not routed to digital i/o, which seems to me a missed opportunity. Again, that weird mix of features and capabilities at work. Incidentally, I also asked how much current the 5v outputs could supply as it isn’t documented anywhere, and I was told around 500 mA. Which is very useful to know.
In any case, timers do appear to reliably fire bang on 1 millisecond – the PWM, despite the video where the phone camera’s own refresh rate is colliding with the PWM refresh rate – appears to my eye absolutely regular. No stutter, though obviously this is not a loaded system.
The proprietary language dScript seems to be a reasonable attempt at a coroutine based BASIC-like embedded systems language. What the language calls ‘threads’ are actually coroutine event handlers, so you declare what event you are interested in e.g. timer elapse, TCP/IP input, board boot, i/o state change and so on, and you write code which will be called when that event occurs. Digital i/o appear to be non-blocking (instant), but analogue input read, serial port read, TCP/IP read and so on appear to suspend the coroutine’s execution until the blocking input completes, upon which execution is resumed. Most writes go into asynchronously flushed buffers and so don’t usually block. Whilst your coroutine is suspended, other coroutines may run. The scheduler is cooperative, so if any coroutine executes for too long, it blocks the execution of other coroutines, and events for a given input after the first event may get dropped as there is no buffering, as befits a hard realtime implementation which cannot allow unbounded dynamic memory allocation.
This coroutine based fixed-at-point-of-compile approach suits well deterministic programming, though it is unavoidably a bit awkward to write code in as a result (think WinRT programming, but minus any dynamic memory allocation). As there is no preemption, there are never races on shared state, which is good because all non-local state is globally visible like say in a single translation unit of C. As all possible memory allocations are known at compile time in the dScript IDE, memory is preallocated for volatile and non-volatile RAM and program bytecode. Strings are supported, but you cannot create new ones programmatically at runtime i.e. with runtime determined length – anywhere you format numbers into a string it preallocates string space for the maximum possible formatted value. There is no floating point support, which is to be expected for such a low end CPU which would lack hardware floating point, but there is what appears to be an optimised boolean expression evaluator which I assume is expanded out into a finite state machine rather than sequences of bytecode for the logic, so if-then-that type logic can be tersely and very efficiently encoded into a constant state table.
Anyway, next weekend I’m going to have a go at writing an actual piece of control software for my particular project in dScript. It’ll have a summary dashboard served as HTTP, so you can always see what state it is at and why. I may or may not also have it push state changes to Home Assistant, e.g. current light brightness, and if I get the time, add remote automation by Home Assistant of the project. I’ll no doubt report on my progress here!
|Go to previous entry||Go to next entry||Go back to the archive index||Go back to the latest entries|