From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.
We appreciate your patience as we improve our online experience.
07-17-2020 08:59 AM
@Bob_Schor wrote:
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
That's an interesting problem. Mine is actually easier as I don't need to have synchronous data between my devices. These are independent and I need independent data from all of them.
So for me, the solution is "just" enabling the different Chip Select lines one at a time, sending my "Read speed" command, save this data and moving on the the next one (Set it and forget it as you say.) and this in a loop, only interrupted by one new command here and there ( I also have to use only 3 registers: Motor ON/Off; Speed/acceleration; Updated speed). The whole process is relatively slow, only 10 samples/s maximum per devices in read, so I have plenty of time to write/read whatever I want in-between samples acquisitions.
I actually don't know what happens if you select all 5 chips, command on MOSI, and then select them indepedently and do a read request.
I know that SPI works in Write&Read at the same time, but if you have access to the code on the chips, maybe you could:
Or another solution could be to go as fast as possible, synchronisation is just a relativistic point of view 😋
Best,
Vinny.
07-17-2020 09:07 AM - edited 07-17-2020 09:09 AM
I'm curious as to what you have so far, save in 2017 and zip and share?
In case you haven't already come to the conclusion yourself, you definitely do not want a separate loop for each station. Here is a couple photos showing what I did to control multiple motors individually:
The first picture is of the GUI for a thermal test application, the second is just a Playground VI in My SmartMotor.lvlib to make sure all the VIs in the library work appropriately before I package them in VIPM. From a user-facing perspective, the idea is that the user highlights which motors they want to start/stop or send commands to (or selects global in the 2nd case).
How that gets handled from an algorithmic standpoint is by indexing over the array of selections and actually doing the action for each element that is turned on. One more thing I'll say is that I keep an array of motor refnums which is how the whole thing becomes scalable. In the first picture, I've essentially limited myself to 4 motors and would have to recode and recompile to add more, but in the second case it's 100% scalable, I could have 10 motors connected with no code modification.
Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.
07-17-2020 09:38 AM
That should do the trick, please tell me if something's wrong, first time I'm saving in a previous version.
@FireFist-Redhawk wrote:
I'm curious as to what you have so far, save in 2017 and zip and share?
In case you haven't already come to the conclusion yourself, you definitely do not want a separate loop for each station. Here is a couple photos showing what I did to control multiple motors individually:
I did, I think that would be the worst to do and actually queuing messages to send is coming kinda naturally to this point.
@FireFist-Redhawk wrote:
How that gets handled from an algorithmic standpoint is by indexing over the array of selections and actually doing the action for each element that is turned on. One more thing I'll say is that I keep an array of motor refnums which is how the whole thing becomes scalable. In the first picture, I've essentially limited myself to 4 motors and would have to recode and recompile to add more, but in the second case it's 100% scalable, I could have 10 motors connected with no code modification.
Can you actually also share your code, you got my attention 🙂
I'm trying to develop an application that would be very user friendly, either using tabs or subpanels in which you can indepedently control and see motors behaviours.
Having an NI USB 8451 at my disposal, guts feeling to easily select channels would be to create 4 different "SPI Configuration" and store them in an array.
What do you think?
Best,
Vinny.
07-17-2020 09:53 AM
Here is the event case that executes when I click "Set Values" from 2nd picture:
@VinnyAstro wrote:Having an NI USB 8451 at my disposal, guts feeling to easily select channels would be to create 4 different "SPI Configuration" and store them in an array.
That is essentially what I'm doing, if I'm understanding you correctly.
Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.
07-17-2020 10:10 AM
Exaclty what I meant. Wasn't sure it would work. Good to know it does.
Thanks!
07-17-2020 12:55 PM
Since you mention that you are reading, let me assume you have an A/D converter, and let's pretend that it has a 1-byte "Setup" command and a 1-byte "Convert" command, after which time 2 bytes of (say) 12-bit Data are sampled from 2 channels (or 4 MISO bytes). You could certainly do a one-byte SPI Write to setup the chip, and then when you want to Convert, do a one-byte SPI Write to Convert, followed (after you are sure all the data are converted) by a 4-byte Write/Read to get the two channels of data back. Then on to the next A/D converter.
Note that you should only need to do the setup once. We set up all of our SPI chips first, then start using them. For the A/D, that consists of a Convert, followed by a Read. For other chips, we follow the protocol for the Chip. When we were just getting started with SPI, we did everything using Write/Read sequences (and threw away the MISOs for "pure writes"), but are now experimenting with a mixture of Writes (for commands) and Write/Reads (just to get the Data back).
Bob Schor
07-20-2020 02:51 AM
There probably is an AD converter, but I don't have access to it and that wouldn't be the goal at all anyway.
(I am given devices that are meant to spin, the goal is to test their performances in acceleration and speed. So I get it, plug it in, start my program and come back 3 hours later with my results 🙂 )
Using spi protocoll, I have access to 4 registers, 3 being "write" (Sending commands like Switch ON/OFF the device; Setting Speed and Acceleration; Software reset) and 1 being "read": The speed register, updated every 100ms by the onboard computer.
That's why my communication is, in fact, quite easy, because everything is calculated on-board, I just send a few commands sometimes, read speed on a regular basis and that's it.
I also have a possibility of controlling bytes sent and received using a CRC algorithm, which I'm not using for now. That makes my communication being only 4B on MISO and MOSI.
When reading, I use the "WriteRead.VI", send 0x00000000 (Speed register adress is 0x00, the rest is data doesn't matter for this register) and I receive 0x00aaaaaa. First B is dummy, then 0xaaaaaa is my actually speed data that I then need to "convert" (from LSB to actual RPM).
I actually have one more question:
I also would like to record the current going through my device(s). Now I'm using a multimeter that has fancy Labview drivers (I've used it before) making it's use easy on labview.
But I'm not sure how to synchronize my data: I want one Speed measurement to correspond to one current measurement. How can I do that? Should I do it in the same loop (doesn't sound good) or another one and somehow synchronize the two (using maybe a notifier? I have never used it before not sure that's how it works). I'll look also a bit on the web, but if there are already some threads existing I haven't seen, would love to have them shared.
Best,
Vinny.