Charles_McG
Ciderwright
First up, some caveats:
a) This isn't an eggTimer Rocketry project. I'm doing on my own, for fun. I did check with Cris about using the egg prefix, though.
b) I'm as much a hobbyist coder as I am a hobbyist rocketeer. YMMV.
c) I'm a biologist and a chemist. And an accidental data scientist. This project has another purpose - to refresh my coding skills for the day job.
So, my goal with this project is to have a live display of data streaming from my 1/5th scale staged sounding rockets. eggTimer released a telemetry module last fall that uses the 900MHz Hope module (like the eggFinders) to stream data back from an eggTimer flight computer. I'm partial to the Proton for the upper stage of my rockets, and the Proton has a pretty rich data set it can send back through the telemetry module. The details are in the eggTimer docs.
BUT - I only have one LCD Receiver. If you're flying with radioed telemetry AND GPS tracking, each needs it's own receiver. Cris has taken pains to make the telemetry packet distinct from NMEA sentences - but they aren't meant to intermingle on one channel. I have 2 USB dongle receivers, and my LCD receiver has the HC06 bluetooth module add-on. So with a laptop with a couple of USB ports, I should be able to make a 'receiver' of my own.
I'm building this project in National Instruments Labview. Partly because I have it. Partly because I know it will make reading the serial data pretty easy. Partly because we have some short term needs in the labs at work that I want to see if I can contribute to. I've coded in Labview before - but it's been a decade or so. Labview has grown in the meantime. For those of you who aren't familiar with Labview, it's coded graphically. The program will look like a wiring diagram. Functions (VIs - virtual instruments) will look like discrete components. Information flows from sources (controls) to sinks (indicators). A function/VI won't execute until all its inputs are available to it. Visually, this 'data flow' programming generally flows from left to right, and top to bottom. But that's a generalization. Structurally, it's like C without pointers. At least it used to be. In fact, the internal written version of the diagrams is called 'G'. Like C, Labview is [mostly] a pretty low level language. It's not event driven. It's not object oriented. Its version of variable scope is pretty limited, and it doesn't have inheritance. New features in the past 10 years push the edges of what I just said - like references (pointers), type definitions, event cases, queues and notifiers. I want to test those out, so this project is [slightly] more complicated than it needs to be, so I can explore the uses of those new tools. Oh, one big difference from C (C wasn't my first programming language - but it's one I worked with a lot. Adapting KA9Q NOS to run on an Atari ST. Nearly back when computers were made of cast iron.) - loops that are not wired together so an order is explicit run in parallel. It's my understanding that they may not be completely multithreaded unless you dig into the options to take more direct control - but for most purposes, they behave like separate threads. Second 'Oh', Labview is used to program LEGO Mindstorm.
Without further ado, let's get started. I opened up Labview 2015 (old, I know, but I had an old license not being used elsewhere.) and started a project based on the 'Continuous Measurement and Logging' template. A three data streams I'm aiming for seem continuous to me, and a quick look showed the VI was using everything I wanted to learn about. Looking at Main.vi...
Every VI has a Front Panel:
So, stop and start buttons, some status and graphing indicators. Alright.
And a Block Diagram
Let's see... some initialization on the left, starting with User Event creation, then a message queue, some clusters (structures in C), a data queue and notifier in the lower left. Go read up about those. Hmmm 'syncronization' tools. A queue is a FIFO stack. A notifier always gives the most recent element pushed. They are 'global' in that they can be called by name from where ever, without explicit wires running all over. Down the middle are 5 parallel While Loops, two having been shrunk down to VIs - maybe to save space, maybe to make development easier. Then some tear down of objects and closing out before finally exiting. (PS - IRL this build has played out over about a week and there was good bit of research, reading, iteration, trial and error, and re-work involved. I'm going to spare you most of that. Also, from this point out, I'm going to use screen shots from my actual build, rather than the template. I just wanted you all to see the equivalent of the body tubes and balsa sheets.
Queue driven state machines (QDSM), I am already familiar with, so let's go check out how Labview is doing user events.
So this is a While loop with a new, special Case structure in it to handle user events. Each Case (like select case) holds the Front Panel Control (it has to be -somewhere- in the block diagram) - but the controls aren't wired to anything. Each case sends a message to the UI QDSM. Here are all the cases. You can see I added more for all the stop/start buttons I added to the front panel.
Right clicking on the case frame brings up a menu that has things like 'add', 'duplicate', 'edit'. From the edit, you can get to the object triggering events:
Not bad, not bad. The old way to do this was to have the 'idle' state in your UI QDSM check for changes in controls since the prior iteration, and throw messages on the queue based on those changes. These new user events and event case structure break the data flow paradigm - but are supposed to be more responsive to user interaction.
I think that's enough for the first post. Time to go get some brandy.
a) This isn't an eggTimer Rocketry project. I'm doing on my own, for fun. I did check with Cris about using the egg prefix, though.
b) I'm as much a hobbyist coder as I am a hobbyist rocketeer. YMMV.
c) I'm a biologist and a chemist. And an accidental data scientist. This project has another purpose - to refresh my coding skills for the day job.
So, my goal with this project is to have a live display of data streaming from my 1/5th scale staged sounding rockets. eggTimer released a telemetry module last fall that uses the 900MHz Hope module (like the eggFinders) to stream data back from an eggTimer flight computer. I'm partial to the Proton for the upper stage of my rockets, and the Proton has a pretty rich data set it can send back through the telemetry module. The details are in the eggTimer docs.
BUT - I only have one LCD Receiver. If you're flying with radioed telemetry AND GPS tracking, each needs it's own receiver. Cris has taken pains to make the telemetry packet distinct from NMEA sentences - but they aren't meant to intermingle on one channel. I have 2 USB dongle receivers, and my LCD receiver has the HC06 bluetooth module add-on. So with a laptop with a couple of USB ports, I should be able to make a 'receiver' of my own.
I'm building this project in National Instruments Labview. Partly because I have it. Partly because I know it will make reading the serial data pretty easy. Partly because we have some short term needs in the labs at work that I want to see if I can contribute to. I've coded in Labview before - but it's been a decade or so. Labview has grown in the meantime. For those of you who aren't familiar with Labview, it's coded graphically. The program will look like a wiring diagram. Functions (VIs - virtual instruments) will look like discrete components. Information flows from sources (controls) to sinks (indicators). A function/VI won't execute until all its inputs are available to it. Visually, this 'data flow' programming generally flows from left to right, and top to bottom. But that's a generalization. Structurally, it's like C without pointers. At least it used to be. In fact, the internal written version of the diagrams is called 'G'. Like C, Labview is [mostly] a pretty low level language. It's not event driven. It's not object oriented. Its version of variable scope is pretty limited, and it doesn't have inheritance. New features in the past 10 years push the edges of what I just said - like references (pointers), type definitions, event cases, queues and notifiers. I want to test those out, so this project is [slightly] more complicated than it needs to be, so I can explore the uses of those new tools. Oh, one big difference from C (C wasn't my first programming language - but it's one I worked with a lot. Adapting KA9Q NOS to run on an Atari ST. Nearly back when computers were made of cast iron.) - loops that are not wired together so an order is explicit run in parallel. It's my understanding that they may not be completely multithreaded unless you dig into the options to take more direct control - but for most purposes, they behave like separate threads. Second 'Oh', Labview is used to program LEGO Mindstorm.
Without further ado, let's get started. I opened up Labview 2015 (old, I know, but I had an old license not being used elsewhere.) and started a project based on the 'Continuous Measurement and Logging' template. A three data streams I'm aiming for seem continuous to me, and a quick look showed the VI was using everything I wanted to learn about. Looking at Main.vi...
Every VI has a Front Panel:

So, stop and start buttons, some status and graphing indicators. Alright.
And a Block Diagram

Let's see... some initialization on the left, starting with User Event creation, then a message queue, some clusters (structures in C), a data queue and notifier in the lower left. Go read up about those. Hmmm 'syncronization' tools. A queue is a FIFO stack. A notifier always gives the most recent element pushed. They are 'global' in that they can be called by name from where ever, without explicit wires running all over. Down the middle are 5 parallel While Loops, two having been shrunk down to VIs - maybe to save space, maybe to make development easier. Then some tear down of objects and closing out before finally exiting. (PS - IRL this build has played out over about a week and there was good bit of research, reading, iteration, trial and error, and re-work involved. I'm going to spare you most of that. Also, from this point out, I'm going to use screen shots from my actual build, rather than the template. I just wanted you all to see the equivalent of the body tubes and balsa sheets.
Queue driven state machines (QDSM), I am already familiar with, so let's go check out how Labview is doing user events.

So this is a While loop with a new, special Case structure in it to handle user events. Each Case (like select case) holds the Front Panel Control (it has to be -somewhere- in the block diagram) - but the controls aren't wired to anything. Each case sends a message to the UI QDSM. Here are all the cases. You can see I added more for all the stop/start buttons I added to the front panel.

Right clicking on the case frame brings up a menu that has things like 'add', 'duplicate', 'edit'. From the edit, you can get to the object triggering events:

Not bad, not bad. The old way to do this was to have the 'idle' state in your UI QDSM check for changes in controls since the prior iteration, and throw messages on the queue based on those changes. These new user events and event case structure break the data flow paradigm - but are supposed to be more responsive to user interaction.
I think that's enough for the first post. Time to go get some brandy.
Last edited: