LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Which QMH template to use for controlling and logging? SPI communication conflict avoidance.

Hi!

 

I am starting to develop a new application and the question of the architecture but mostly how to adapt a template is coming in. I am not experienced enough in QMH to fully understand how it works and I'd need some advices.

 

Here are my thoughts:

I basically need to command&read up to 4 motors indivudually. All the control is done on their embedded PCB, So I basically just need to tell them to:

  • Start/Stop
  • Speed and acceleration
  • Read/log their speed.

Communication is done via SPI and I have a USB-8451 I²C/SPI adapter from NI (https://www.ni.com/en-gb/support/model.usb-8451.html) I also need to read/log their current cousumption using an Agilent 34401.

 

The idea is to be able to individually and manually or automatically (via a time scheduled commands for instance) command all four motors and save the read data in a TDMS file.

For instance, a typical case would be:

  • Start a sequence for Motor1 that'll run for 2 hours and continuously acquire&log its speed (and current) in the background.
  • Do some manual test with Motor2 in the meanwhile without logging them but visualising its speed.

 

So I'm thinking that Continuous Measurement and Logging template sounds like a great match. But I'm just unsure on how to deal with the multi control of the motors:

  • Should I have one separate While Loop for every motor with its own communication?
    • Not great for future development
    • Easy to implement
    • potential big issues in protocol communication (trying to communicate with two wheels at the same time)
  • Should I have One loop for the communication, handling the commands sent and received and forwarding them to the proper "motors log"?
    • A bit more complicated to handle
    • Better for future dev
    • Communication "slower" (?)

I am still reading on the use of this template (within the code there is a lot of documentation), but it is not super clear what changes implies what and having some help on this would be awesome.

 

Thanks a lot in advance for some advices and insights.

Vinny.

0 Kudos
Message 1 of 17
(3,100 Views)

Sometimes it helps to design for a single "station", get all of the bells and whistles figured out, then start thinking of how to replicate the code to run multiple copies simultaneously (and if that is even possible!).  One concern is that you have a single SPI Master device that not only might (??) need to communicate with multiple SPI Slaves on a single Station, which could probably be done in some defined order so one command does not "stomp" on the data of another command, but when you have one Master trying to talk to multiple Slaves asynchronously, the timing might get a little hairy.

 

You also have an Agilent device (I'm unfamiliar with this Product) doing other DAQ chores.  Is it capable of independent asynchronous DAQ tasks across your various Stations?

 

When I've tried doing this, I had multiple sets of hardware and could assign one set to each Station.  This made it simple to create a "One Station" routine (which I based on a QMH-like design pattern, but using Messenger Channel Wires, so I called it a CMH) which managed the Station.  It had, in turn, three sub-VIs, two being CMH loops that managed two pieces of Acquisition hardware, and the third that managed the Data-saving tasks, starting and stopping the data files based on signals from the two DAQ devices.  At Run Time, I simply fired up as many of these Station "clones" as I had active Stations (I designed it for 24 Stations, but my hardware and Ethernet capabilities made 9-10 the "practical" limit ...).

 

Bob Schor

0 Kudos
Message 2 of 17
(3,027 Views)

Hi Bob.

Thanks for your reply, but I have to say that you lost me somewhere in there haha

 

What are you calling a "station" ?

 

While putting aside the agilent for now (it's really not what worries me), very quickly it's just a multimeter that has a remote control (USB, GPIB ....) enabled and I would use it to record the current going through one or all my motors at the same time.

 

So after thinking a bit more about it what I have in mind now is to have one loop with its own queue for communication only with all my devices. That would avoid any problems like "Command 5000rpm to motor 2" but it sends it to motor 1 instead because the motor 1 was still enabled.

As commands are sent randomly by the user and it would take only a bit more than 32us (freq of 1MHz and 4 bytes to send) AND the calculated speed register is updated only every 0,1s on the devices side... With 4 motors I still have plenty of time to send all the commands I want independantly to reading their speed.

 

So globally I would have X while loops:

  • The event handling loop
  • The UI loop
  • The command&read loop
    • This one would then continuously read the 4 motor speeds on after the other and whenever the user send a new command to one of the wheel, this one is queued and executed between 2 reads
  • The Logging loop
    • Receiving data from the Command&read Loop

 

In the end, I would just have to use the CM&L template and change the acquisition VI I guess.

 

What do you think?

Am I missing an important point ?

 

Vinny.

0 Kudos
Message 3 of 17
(3,017 Views)

As I understand it, you are going from thinking about studying one system (motor, something) with a QMH model to working with 4 independent systems (of the same type).

 

A "station" is a "unit of equipment under test".  Before worrying about "how can I do four of these, independently, and simultaneously", design a system to do "one station".  If you want to replicate the system that worked to gather data from a single station (whatever it is), the way we did this was to develop the "station" concept.  Each "station" ran the same code, but the DAQ code took the "Station number" into consideration in tailoring the code for the hardware associated with that station.

 

The main point (which I probably didn't state clearly) is we developed a system that worked for one set of devices, got all the bugs out, and then figuring out how to do the same thing for a second, third, fourth, ... set of hardware.  Figure out how to do it for 1.  Now figure out how to do it for one more.  [Mathematicians would recognize this as related to the Principle of Induction ...].

 

Bob Schor

Message 4 of 17
(2,988 Views)

@Bob_Schor wrote:

As I understand it, you are going from thinking about studying one system (motor, something) with a QMH model to working with 4 independent systems (of the same type).

 


Ah yes that's how I am doing in practice right now (I'm also veeeery new with SPI -and kindof other non-so-usual  - communications, so I'm also testing that part.)

 

But I'm also new with QMH (using variant and all) and I was looking for some advices on how to deal with it.

 


@Bob_Schor wrote:

A "station" is a "unit of equipment under test".  Before worrying about "how can I do four of these, independently, and simultaneously", design a system to do "one station".  If you want to replicate the system that worked to gather data from a single station (whatever it is), the way we did this was to develop the "station" concept.  Each "station" ran the same code, but the DAQ code took the "Station number" into consideration in tailoring the code for the hardware associated with that station.

 

The main point (which I probably didn't state clearly) is we developed a system that worked for one set of devices, got all the bugs out, and then figuring out how to do the same thing for a second, third, fourth, ... set of hardware.  Figure out how to do it for 1.  Now figure out how to do it for one more.  [Mathematicians would recognize this as related to the Principle of Induction ...].

 

Bob Schor


Yep understood.

So far, my plans are

  1. Be able to control 1 station.
  2. Record&log its speed
  3. Implement Current acquisition
  4. Implement automatic runs
  5. Expand the application to more stations

For now I still don't know how I will be able to send a series of bytes in a specific adress on my station, but that'll come 🙂

 

Thanks for your help Bob.

0 Kudos
Message 5 of 17
(2,973 Views)

Hi.

 

After struggling a little bit with bytes management, I can now fully control 1 station 😅

However, for my test I've used the producer/consumer template and I feel like I haven't used it properly, especially for my constant reading and idle state.

 

I think that I need to add a state machine inside my consumer loop as I was having issues of states alternating because of the queue not flushed.

I'm attaching the project here, but I'm using the NI USB-8451, to open it properly you might need the drivers, so I'm just adding one picture to illustrate what I meant above.

If you have any comments or advices I'd be happy to read them 🙂

 

Vinny.

 

VinnyLaTaupe_0-1594630466723.png

 

0 Kudos
Message 6 of 17
(2,942 Views)

Wow, that was so disorganized!  You have a QMH that doesn't do the "Initialise" State (which, I naively think, should be done both first, and once, not on an unobvious Button push).  When I've used a QMH-like structure, I've usually had a sequential State Machine in mind, and treated the QMH as though it were a Queued State Machine, most of the time the "next State" coming at the end of the current State, and sometimes because of User Interaction.  That might be true here, but it is very difficult to follow.

 

To complicate things, you are using SPI, which has its own interesting Protocol issues.  

 

A technique I've found particularly helpful is to break out a Word Processor and "Write the Documentation First".  Describe what (not "how") you want to do.  Try to reduce it to 4-8 "States", the first one of which should be "Initialize", and one of which should be "Handle Errors", with the last one being "Shut down safely".  Maybe State 2 is "Get Input Parameters", then "Do Command" and "Get Results".

 

Now flesh it out.  "Do Command" might be "Send SPI command to set up A/D converter" followed by "Get Values" (which sends a SPI command to ask the A/D Converter to do a Conversion, followed by a SPI Write/Read to get back the Values).

 

I also have an Event Loop, the purpose of which is to respond to Front Panel Events and pass the relevant Parameter to a State.  If it is a changed "Input Parameter", the State merely saves it in a Shift Register for the (later) State that needs it.  If it is a "Go" button, it just puts me in the "Start Doing Something" State.

 

Bob Schor

Message 7 of 17
(2,935 Views)

Wow to be honnest I was not expecting such a negative feedback 😅 But thanks a lot, helps me having a better understanding of what I should do.

 


@Bob_Schor wrote:

Wow, that was so disorganized!  You have a QMH that doesn't do the "Initialise" State (which, I naively think, should be done both first, and once, not on an unobvious Button push).  When I've used a QMH-like structure, I've usually had a sequential State Machine in mind, and treated the QMH as though it were a Queued State Machine, most of the time the "next State" coming at the end of the current State, and sometimes because of User Interaction.  That might be true here, but it is very difficult to follow.

So while writing my answer I just realized my mistake: I had this "Initialise" state sent in the queue at the very beginning instead of "Idle". But because the init is pretty straight forward (creating the spi thread with basic parameters) and my goal for this application was to quickly be able to control my station, I got annoyed to have my settings window popping up all the time (Was popping because the documentation I have isn't clear on the spi mode and all, so some quick tests were necessary. Once this done, I didn't need the pop-up anymore on program start.)

So I took it off this morning thinking that the constant parameters initialising the shift register would be enough, didn't try it out and sent it here. But I understand it is a bad thing to do.

 

In the end, I also mixed Initializing and Settings.

 


@Bob_Schor wrote:

 

To complicate things, you are using SPI, which has its own interesting Protocol issues.  

 


That, I don't have a choice saddly, but if I could I would definitely use another communication protocoll!

 


@Bob_Schor wrote:

 

A technique I've found particularly helpful is to break out a Word Processor and "Write the Documentation First".  Describe what (not "how") you want to do.  Try to reduce it to 4-8 "States", the first one of which should be "Initialize", and one of which should be "Handle Errors", with the last one being "Shut down safely".  Maybe State 2 is "Get Input Parameters", then "Do Command" and "Get Results".

 

Now flesh it out.  "Do Command" might be "Send SPI command to set up A/D converter" followed by "Get Values" (which sends a SPI command to ask the A/D Converter to do a Conversion, followed by a SPI Write/Read to get back the Values).

 

I also have an Event Loop, the purpose of which is to respond to Front Panel Events and pass the relevant Parameter to a State.  If it is a changed "Input Parameter", the State merely saves it in a Shift Register for the (later) State that needs it.  If it is a "Go" button, it just puts me in the "Start Doing Something" State.

 

Bob Schor


I technically have my requirements already (The "what" I need). I created this thread because I was trying to answer the "How"

Thanks again for your advices about the structure, I'm working on improving this code already 🙂

 

Best,

Vinny.

0 Kudos
Message 8 of 17
(2,929 Views)

Hi!

 

Ok, there is still quite some work to do in general, but I believe I've made some progress, at least in understanding how to deal with QMH.

 

More specifically, I still need to implement the Error Management. As I don't know yet what kind of errors are/will appear for now, I just preferred to make it working for now.

I also don't have any logging/proper displaying loop : the data is directly sent to a chart in my communication loop for now just as a proof of "communication works fine"

 

I tried to make it easier for future development (multiple stations) But I am still unsure how I will manage controling and recording stations indepedently (probably using multiple spi config in an array, OR using SPI scripts)

 

Will be glad to hear some feedback of my current progress in using this kind of Architecture, hoping it'll be better than last time 😄

 

Best,

Vinny.

0 Kudos
Message 9 of 17
(2,892 Views)

The "problem" with SPI is all the SPI devices "share" the same four signals, Chip Select, SClock, MOSI, and MISO.  While talking to one Device, you need to keep all four lines dedicated to your SPI Chip, which basically means that you can't easily run SPI Chips in parallel (unless you have independent "sets" of the four signals).  And if running single Chips in parallel is tricky, how can you plan to run multiple stations, each having a set of Chips, in parallel?

 

I'm currently wrestling with exactly this problem.  I've got multiple boards designed to operate "in parallel", each with 5 SPI chips:  3 16-bit Digital "Registers" (used to turn on/off specific Board options, set at the beginning and largely left alone afterwards), one D/A converter to set a (relatively-constant) analog signal, and an A/D converter, designed to collect 4 channels of data synchronously with the other boards.

 

I'm not an Engineer, so forgive the hand-waving explanation that follows!  To deal with the 5 SPI chips on the board, we used a 3-bit register to select Chip 0, 1, 2, 3, or 4, and routed Chip Select to the appropriate SPI chip.  Doing this, we could selectively write (MOSI and SClock) the 5 chips individually, and could MOSI/MISO them to get the data back.  Of course, we could only do this one chip at a time, but that was typically not a problem, as most of the Chips were "set it and forget it", i.e. they were constant for long periods of time.

 

We are still developing this SPI code.  We know that it works for a single Board (we've tested it using the NI USB-8452), and are thinking about the multi-board "parallel" A/D sampling problem ...

 

Bob Schor

0 Kudos
Message 10 of 17
(2,882 Views)