arduino3 branch (along with ArduinoMsgGenerator) and MRLCOMM version 46 has been merged into develop branch ... WHOOHOO !
publishPinArray and enablePin appear to be working with new ArduinoMsgGenerator framework now...
(on arduino3 branch)
I've pushed all the stuff I have been working on into a new branch called arduino3.
All the important stuff is in src/resource/Arduino/generate
They include all template files & the arduinoMsgs.schema.
A huge amount of power is given to the one who changes the schema.
You can change method signatures then run
ArduinoMsgGenerator
And all the RPC methods will be created for you.
I've tested all the documented data types - pick what is appropriate for your method calls.
Once the generator runs, you can upload the new code in an Arduino and call it from the Arduino service, or call any Arduino service method from MrlComm.
The compiler will do type checking and verify any methods expected are implemented in some form (very nice!)
At the time of writing I had Servo working - none of the other devices I have checked, but done a first pass, best effort on trying to re-implement them.
I need your help ! I'd like anyone interested to try to understand the pattern and make use of it. I suspect Arduino service will go through further refactoring. Its becoming more and more a transparent "pass through" to the C++ code into MrlComm.
Besides the message generator and the (I think) solid & easy to maintain RPC code, there are a few other really big changes..
1. Arduino service owns the deviceId.
2. There are no (or few - which need to be removed) while(x != null) sleep loops. Initial connect is done with thread locking - and it works without any unecessary wait time. MrlComm start talking first, Arduino service is listening.
3. publishBoardStatus comes back with an array of deviceIds & deviceTypes (Yay)
4. Rebuild of devices should be possible and fairly easy - ie complete disconnect & power outage of MrlComm/Arduino Hardware -> reconnect -> send all device info -> back to were you were.
I think this is a new level of robustness.
5. Attaching devices is explicit - previously all config data on deviceAttach was sent into an object array. This is still done in the DeviceMapping, but only to preserve the data for future disconnect/rebuild of the deviceList.
Patterns : - the concept of 'attach' we want to provide as a high level interface to the user or builder of a script - where it's easy for them to attach services with other services. To attach a MrlComm device to the deviceList with initialization data -> it needs to be explicit
I've created servoAttach as an example for other devices.
In general there should be "NO PARSING, OR BIT OPERATIONS" needed in human created code.
I hope we can go through the rest of the devices, clean Arduino code, and quickly get this branch merged back onto develop
YAY !
i2c
Hi GroG
I pulled the arduino3 branch and started to look at the code.
To expain how I have been thinking in the current i2c implementation:
An i2cBus represent the physical 2-wires. It is very similar to a serial line.
An i2cDevice represents any type of i2c enabled device like the Adafruit16CServoDriver, OledSsd1306, Mpu6050, Bno055 and so on.
In MRLComm a device represents an object with a set of methods. In the case of i2c only one set of methods is needed even of you connect multiple i2cDevices to the same i2cBus. So to preserve memory in MRLComm only one device/object is created. It represent one single i2cBus.
So I will change i2cAttach in the schema to i2cBusAttach to make the difference clear.
i2cBusAttach will be an internal Arduino method that corresponds to the i2cBus object creation in MRLComm.
i2cAttach will be the method used in the i2CController interface used by all the i2c devices
I hope this makes sense.
/Mats
It does It does make sense !
It does It does make sense ! :D
Great,
excellent plan, and I think the MrlSerial device should behave the same way...
Hi Grog Yesterday I have take
Hi Grog
Yesterday I have take a small look on what to do to make the neopixel service worky again. With a small change all seem to go errorless, but I have not test yet with a physical device.
It look very great, but i'm still a little bit confuse about how to implement new things and generate all the code need to have it work.
Let said I want to implement the following method -> newServiceMethod(byte deviceId, long data1, byte[] data2)
Can you descripbe the step need to implement it and have everything generated?
Another thing I have notice, at least for neopixel service, is that you use byte deviceID, I think we should use a bigger holder than byte because if the deviceID increase everytimes a device get attach/detach, the maximum value will be quickly reached.
Sure Calamity, I was thinking
Sure Calamity,
I was thinking perhaps I should begin with MrlSerial device, which I would propose to relay serial data (since MSG_ROUTE) was removed.
The first thing is to start with arduinoMsgs.schema. This file controls both Java & C++ communication.
I add the following lines to arduinoMsgs.schema
# Serial - for relaying serial data to a different pin
> serialAttach/deviceId/relayPin
> serialRelay/[] data
< publishSerialData/[] data
I'm guessing we might need a target pin to relay the serial data to, then a method to send a byte array, and another to recieve reads from the pin.
Previously, there was only a single attach and we had to parse the config data to satisfy the needs of our device. Now we explicitly have a {deviceType}Attach method which all its initialization config is specified. Once the arduinoMsgs.schema is saved. Run ArduinoMsgGenerator.
Running this class generates the following code for our 3 new lines.
In MrlComm.h it ads the following definitions
The very nice part of this - is the compiler will complain that you did not implement these in MrlComm.cpp :)
The publishSerialData is not here because its designed to go from MrlComm to Java. Our two above functions are "control" so they should be defined here.
publishSerialData got defined in Msg.h
Now lets look at Msg.cpp
Pretty simple for this method, just write a byte array to the return serial stream. One of the challenges of getting the autogenerate code to work was correctly calculating the size or (going the opposite way) calculating the positioning and parsing. But both of these mundane tasks are auto-magically done for you when you use ArduinoMsgGenerator.
Ahahaha : so I forgot the deviceId in the schema :D
This would be a pain if I had hand coded all this muck .. but it takes just a couple seconds to update the schema to this :
This is Msg.java - and its completely controlled by ArduinoMsgGenerator -
It created the following method. It will correctly parse and invoke the appropriate method in Arduino.java... you just need to implement it ;)
Java can now
msg.serialRelay(deviceId, buffer);
That is indeed very simple
That is indeed very simple and very less prone to error, great job and thank you for the explanation
Mats .. please remind me -
Mats .. please remind me - why is it
Control.attach(Controller, params...)
vs
Controller.attach(Control, params...) ?
I'm looking at the old scripts for UltrasonicSensor and they are reversed..
http://myrobotlab.org/service/UltrasonicSensor
Ambiguity generates bugs and confusion .. I suppose both could be supported but the details of connecting, and driver loading will always be in the Controller not the Control..
So Control.attach(Controller) will/should always just call Controller.attach(Control) ..
Sorry, my failing memory will be the death of me ....