-
First version of driver software complete!
07/06/2017 at 03:09 • 0 commentsAfter some testing and reorganizing, the E32-TTL-100 lora module driver implemented in rust is now complete!
You can find the source here: https://github.com/ddemarco5/lora_driver
It's configured as a crate, so if you want to include it in your own RUST project, all you have to do is add this to your Cargo.toml (assuming you're using cargo)
[dependencies] lora_driver = { git = 'https://github.com/ddemarco5/lora_driver.git' }
and add these use statements in the beginning of your rust fileextern crate lora_driver; use lora_driver::RadioConfig; use lora_driver::Driver; use lora_driver::RadioMode;
and you're good to go!I plan on updating it as I require/see fit as the project continues, so a word of warning to anyone who wants to jump on the bus immediately. Though based on how much attention this project is getting I'm assuming that won't be many of you :P
Besides that news, I'm going to be starting the actual full-duplex serial emulator soon.
Before that though, I think I'm going to run a few tests to see what sort of speeds/power consumption I can expect out of these things. The packet transmit rate is anywhere from an advertised 1k to 25k, so I'll actually need to test those.
Based on preliminary results though, I can attest to the fact that the 1k mode is SLOW. I'm talking somewhere around 2-3 seconds to transfer 256 bytes of data.
Though there's a somewhat undocumented reason for that... I'll explain below.
What first tipped me off to it was the power drain I was seeing on my power supply. I sent the documented 256 bytes to the device for transmit, and I could see the power drain hop up to 100mA immediately, it was drawing current as was specified in the doc, but something was odd. Every second or so the power consumption would drop down to 70mA for a short while and then back up to 100mA.
I could actually hear very slightly the noise made from the radio in speakers I had close by, so that also tipped me off to the radio's activities.
When the power draw dropped to 70mA, the radio would stop transmitting... odd.
I went to a serial monitor program on my C.H.I.P. device to see what was up, since I wasn't receiving the full data I was expecting in my rust program, and there I saw the culprit.
The radio was actually sending FIVE data packets of 58 bytes each. When the power draw of the radio was dropping, that was the internal circuitry moving 58 bytes from its internal buffer into the LORA chip for transmittal.
The max packet size is NOT 256 bytes as the original documentation suggested, but 58 bytes instead.
The chip has a UART buffer that can be filled with up to 256 bytes, and the gpio outputs from the chip indicate whether or not THAT buffer is full, not the max packet size of the LORA radio.
This is interesting functionality, but unfortunately I'll be unable to make use of it in the serial emulation portion of my project, because the radio is already introducing overhead per packet, it will be of no value to me to send data any larger than 58 bytes to the radio. If I don't split the data in to 58 bytes per packet, the radio will instead.
The only impact that would have on the final project of this project would most likely be an increase in latency, unfortunate...
HOWEVER, since I'd like the driver software I wrote to be general purpose enough to be used by other people, I've left the ability to read an entire 256 byte packet in as well. The code makes use of a timeout function on a serial read to ensure there is no more data left in the serial buffer to be read.
I will, however, have to expose the ability to customize that timeout value, because based on the transmit rate the radios are set to, you may have to end up waiting for around 2 SECONDS for another data packet to come through. Yes... it can be that slow.
Progress is promising though! I'll post some updates after I've done some benchmarking of these devices to see what kind of data rates I might be able to expect when all is said and done.
-
First Contact!
07/04/2017 at 02:26 • 0 commentsWe have our first data sent!
Though we're not out of the woods yet. There's still a bit of work to be done on the driver portion.
Here's what I have more or less completed:
- Control of tty port on both C.H.I.P and Vocore
- Programmatic control of radio device settings. Baud rate, address, transmit power, etc.
- Sending packed of up to max size (256 bytes)
What I have yet to master is the receiving of the data. While it looks all well and good above in the screenshot, if I send a large packet, the receiver only receives 58 bytes at a time.
I should clarify, the ENTIRE packet is sent and received by the device just fine, it's a software problem that I have to tackle.
The issue lies in the very name of he UART connection: Asynchronous.
The way the radio sends data out of itself to the parent device is by alerting the device is busy by setting the AUX pin low, sending its data out 5ms later, and then setting the AUX pin high when it's ready for work again. Problem is, when the aux pin goes high, the radio isn't DONE sending the packet data out. It's simple ready to receive more.
How I'm going to reliably grab all the serial data without using a CPU intensive polling method is something I'll have to think about. I'll have to poke through the libraries I'm using to see if they've already implemented something of the sort, and if not I'll have to mull over what options I have.
That's a problem for another day though. For now I'm rather happy with the progress I've made.
-
Learning experience.
07/01/2017 at 23:28 • 0 commentsIf you read the last log I have to apologize. The issue was not with how the serial was framed. I read the documentation more and sending it byte by byte was perfectly acceptable.
The issue I was having was a physical one. I had wired up the radio to the C.H.I.P. with a man in the middle, a USB-RS232 converter. I set it up that was just assuming that would work, turns out it's very much not the case. You need some special hardware and a couple of components to make that work well.
However, I did finish up the code to communicate with the radio and send configuration data to it, and it receives it and makes the changes to itself, yay!
I ended up using a serial library for rust that I do NOT like. I disagree with how he set up the objects that represent the serial connection. It makes it bulky and hard to work with.
The only positive I can get from it is it has a "timeout" feature that throws an error if we're waiting for data for too long, but that's the ONLY feature I can't replicate myself with a lot less code/complexity.
If I get free time I'm going to rewrite that portion.
Good news though, the next step is writing the simple routines to send a block of data to the radio through the UART connection and have it transmit it wirelessly!
If all goes well, I should have some picture/video of that working in the next couple of days.
And once the driver code is at a point where I don't feel ashamed calling it version 0.0.1, I'll put it into its own library and start on the half-duplex to full duplex portion!
-
Burning the midnight oil.
07/01/2017 at 04:25 • 0 commentsIt was a late one tonight.
I finished up the code to send configuration strings to the radio and went to test it out, but was having some trouble. I was getting the response I was expecting from the radio from a serial console attached to a USB-RS232 dongle I had wired up in line between the C.H.I.P. and the radio, but I wasn't getting a response from the radio when I sent what looked like the EXACT same data from the C.H.I.P. to the radio itself... I was stumped for a while.
As it turns out I should've done a little more research, and UART isn't as simple as writing some characters to the /dev/ttyS0 device. There's framing that goes on in the background. The USB-RS232 dongle was taking care of it for me, so I never actually saw the frames in the hex data I was looking at on my development computer.
Lesson learned...
I spent the rest of the night tracking down a usable library for rust that would take care of all the protocol details for me. I found one that would work for my purposes but I was having an immense amount of trouble getting the Rust crate to be recognized.
It took a helpful user on the Rust discord channel to help me find out that it was a bug in the serial library I had chosen. The dependency for the mipsel target (my Vocore) was missing, so it seemed like the library was invisible to the code that needed to make use of it.
After fiddling with a local copy of the library I managed to add the line I needed and told Rust to "replace" that library with my local copy.
After all that work I got the message I was looking for:
Finished dev [unoptimized + debuginfo] target(s) in 12.15 secs
An errorless compile...Now that I've seen that I'll be able to close my eyes and actually be able to sleep.
I'm hoping to get a PROPERLY framed UART packet sent to the radio from rust within the next day or two.
But for now, some much needed sleep.
-
And a little further
06/29/2017 at 02:48 • 0 commentsWorked a little more on the radio driver code today. I created the scaffolding for configuring the radio. I spent a while trying to figure out how exactly I'd do it. A true object oriented method would be an incredible amount of code and be truly tedious for the user, as it would assume the user had no access to the radio's datasheet. Everything required to use it would have to be visible in the doc generated from the rust code.
However I didn't want a hack solution either, assuming that I would be the only one using this and it'd be good enough for me.
I decided on a happy medium. I'm going to make it relatively object oriented. The actual configuration will indeed be an object itself, but to change a portion of the config I will create a function for the configuration object that will take in a literal and use pattern matching to figure out what to do.
For example, in the end the code will look something like this
let radio_config = RadioConfig::new(); RadioConfig.speed("9600");
to set the speed of the UART connection to 9600 baud, instead of knowing that they have to make bits 7,6,5 of the 4th character of the command string '001'.
This way I won't want to pull my hair out if I come back to the project a little while later, or if someone else decides to build a copy of my project when they're done.
-
Driver work begins
06/28/2017 at 01:45 • 0 commentsToday I had to switch my testing over from the Vocore to the C.H.I.P. due to not actually having any free 3.3v outputs. They were all taken up by the attached dock... whoops... I'll have to figure out how to work my way around that one.
Good news is, the code when run on the C.H.I.P. worked flawlessly, the sysfs code works on both platforms without have to add any sort of macro logic, which is wonderful.
Today was the first time I actually plugged the radio into one of the devices and nothing caught on fire thankfully. Work is a little slower than I'd like because instead of just bit-bashing this together in python I'm using a new language to me, and writing it in a fashion where I won't be embarrassed if another human looks at it.
Here is the datasheet for the radio I'm using in particular http://www.inhaos.com/uploadfile/otherpic/DS-RF-TTL-100-V01-EN.pdf
I completed the ability to change the mode the radio operates in, because in order to configure the internal settings of the radio, I need to place it into "sleep" mode and send it a specially crafted string over its UART connection (still currently unconnected).