Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
3 inputs to 3 solenoids 1:1
#1
Hi there,

In my current rig I'm trying to incorporate the Bpod into our current setup as a switch/solenoid trigger. Can I simply control 3 solenoids (output is behavior ports 1:3 to Bpod port interfaces) from 3 input channels? I basically want to have an external arduino board (running firmata) that has 3 of it's digital channels connected to the Bpod, so that each input channel can trigger a solenoid burst. On the back of the Bpod (r.07) there are 2 wire terminal i/o's, but each has a different polarity 1+, 1-, 2+, 2-, so getting a 3rd might be a bit tricky.

Travis
Reply
#2
<update>

Hi Josh,

Here's a quick update, so I'm using r.07, and found from your previous help (thanks!) that the wire terminal input port is channel 31, and the Behavior port 1 is channel 28. With this in mind I put a small bit of code in the arudino firmware:

void startSM() {
  
   int val = digitalRead(31);  
  digitalWrite(28, val);
  if (val, HIGH){
    delayMicroseconds(100000);
  }

in the hopes that if the BPOD would link the input to the solenoid, and if it's high give it a good second or so for the solenoid to go off. I just realized however that the channel 28 is the behavior port, which is an ethernet cable (controlling a valve, LED and POK), so I'll have to reverse engineer how the command to turn on the valve is given. I assume it uses one of the subfunctions/modules, like 'digitalWriteDirect(valveCSChannel, HIGH);' 

If I'm lucky and you read this while I'm trying to figure it out, it'd save me a ton of time if you could let me know which it is, otherwise no worries, I'll just keep reverse-engineering the code.

Cheers!!

T
Reply
#3
Hi Travis,


In our latest state machine (r2), there is one digital Arduino pin per valve, so it would have been simpler - but on your model (0.7) the valves are driven by a shift register, which accepts instructions via the SPI bus. You'll need to mod the valveWrite() function from the firmware (use ctrl-F to search for it, here). The gist of the function you'll need to create starting with valveWrite() is to initialize a byte to 0, then use a call to bitSet() for each valve you want to turn on, then call SPI.transfer(your byte), then flip the chip select line high and low.

I hope this helps!
Reply
#4
(06-06-2018, 07:13 PM)Josh Wrote: Hi Travis,


In our latest state machine (r2), there is one digital Arduino pin per valve, so it would have been simpler - but on your model (0.7) the valves are driven by a shift register, which accepts instructions via the SPI bus. You'll need to mod the valveWrite() function from the firmware (use ctrl-F to search for it, here). The gist of the function you'll need to create starting with valveWrite() is to initialize a byte to 0, then use a call to bitSet() for each valve you want to turn on, then call SPI.transfer(your byte), then flip the chip select line high and low.

I hope this helps!

Hi Josh, yeah I saw r2 had more inputs, but what-can-ya-do, we have 2 r.7's, but if we can get this to work we'll need more for the other rigs so we'll probably go with r2's. Thanks a lot, this helps butt-loads!!!

T
Reply
#5
(06-06-2018, 07:13 PM)Josh Wrote: Hi Travis,


In our latest state machine (r2), there is one digital Arduino pin per valve, so it would have been simpler - but on your model (0.7) the valves are driven by a shift register, which accepts instructions via the SPI bus. You'll need to mod the valveWrite() function from the firmware (use ctrl-F to search for it, here). The gist of the function you'll need to create starting with valveWrite() is to initialize a byte to 0, then use a call to bitSet() for each valve you want to turn on, then call SPI.transfer(your byte), then flip the chip select line high and low.

I hope this helps!

Hi Josh, your suggestion worked!! With this code I can turn solenoid 1 on or off:

int valve_val = 1; 
byte value = 0;
    int i = 18; /* Solenoid 1 */
    bitSet(value, valve_val);
    SPI.transfer(value);
    digitalWriteDirect(valveCSChannel, HIGH);
    digitalWriteDirect(valveCSChannel, LOW);

Now to what I thought was the easy part, but is turning out to be a harder part. I assumed the Wire terminal inputs would read in just like an arduino digital channel. From the channel mapping I found that Wire terminal 1+ = 31, so I wrote this code as a gateway to turning the valve on or off:

int val = digitalRead(31);
  int valve_val = 0;
  if (val, HIGH) {
    valve_val = 1;
  }  

I send a TTL to wire terminal 1+, but nothing happens so here's my question to you: are the wire terminal channels handled just like arduino digital channels, ie reading from them would then result in a HIGH or LOW answer. I noticed they are defined with 'byte' up above and didn't know if this changed anything.

Soooo close!!!! I feel like the hardest part is past. Additionally, I'm thinking of using wire terminal 1- as an input channel, rather than a ground. It looks like it's connected to arduino channel 32, so I could use 31, 32, 33 for my 3 input channels to control solenoids 1, 2, 3.

T
Reply
#6
(06-06-2018, 07:13 PM)Josh Wrote: Hi Travis,


In our latest state machine (r2), there is one digital Arduino pin per valve, so it would have been simpler - but on your model (0.7) the valves are driven by a shift register, which accepts instructions via the SPI bus. You'll need to mod the valveWrite() function from the firmware (use ctrl-F to search for it, here). The gist of the function you'll need to create starting with valveWrite() is to initialize a byte to 0, then use a call to bitSet() for each valve you want to turn on, then call SPI.transfer(your byte), then flip the chip select line high and low.

I hope this helps!

Hi Josh,

I got everything to work, but I think I may have damaged it!! Here's the situation, I've reprogrammed the output ports to be input ports and can activate solenoids via mapping with the new input channels. I then realized that I'll need a flush the line before and after running, so I used one of the digital inputs (31) to trigger all 3 solenoids, and was going to put in a button on a bread board so that I can manually trigger them. solenoid ethernet ports started getting stuck, where they won't discharge, so I tried running this through the matlab software and realized that when one solendoid is on, it grays out the remaining solenoids. I then checked online and i saw that you say that only one solenoids at a time can be on, so I seem to have bypassed that. 

1. Can you confirm this, that with the r.7's only one solenoid should be on at a time?
2. Have you witnessed this 'breaking' of the ethernet ports during your development stages?
3. Is there a remedy or are those ports just toast? Since I only need 3 I can use some of the other ports and salvage this rig.
4. I suppose to flush the line I'll have to do that one at a time then, and write some code to protect against this happening (which you probably already had written Smile

I still have a perfectly fine backup bpod r.7 I can use once I iron out the kinks with this one.

Travis
Reply
#7
Hi Travis,

The wire input channel goes through an inverting isolator - so from Arduino's prespective it will read high by default, and low when you drive the line high.

Unlike for state machine r2, r0.X supplies 12V for the valves from the USB supply, via a DC/DC converter. Other onboard circuitry consumes a lot of power - so with several valves open you'll exceed the USB spec of 500mA. State machine r2 solves this by switching an external 12V source to the valves using an isolated driver IC. This keeps the current transients separate from the high-speed digital circuitry on the board. For r0.X, I restricted the number of valves to 1 in the override panel. You may be able to get away with 2 if you connect a 12V supply (1A, positive center) to the state machine's power jack (though I'd test for reliability).

I'm not sure what the symptom you're seeing is - do the valves open and remain stuck open? If you power-cycle the state machine (unplug and re-plug), do the broken valves open immediately on power-up? If so, I haven't encountered that problem in the past. I'd caution against opening the valves for prolonged periods of time - typical reward dispensing is 10-100ms. Some valve driver circuits avoid heat dissipation (and prolong valve life) by stepping to a lower current once the solenoid is open ("hit and hold"), however Bpod's current firmware does not do this.

Josh
Reply


Forum Jump: