To control solenoids with dynamics, I adapted Reduzent's [Solenoiduino] abstraction and arduino sketch to include the TLC5940 functions, which is what the Practical Maker PWM shield is based on. So far, I'm able to control 44 solenoids using custom drivers and 2 stacked PWM shields. This is an excellent alternative if you want to build a relatively cheap electro-mechanical piano setup.
The problems i've run into:
dropped (this happens a lot) 2. the handshake does not seem to work on Linux (Ubuntu 11) 3. the original code only supports 16 solenoids
This last one is the one that goes over my head, since the code uses that bit twiddling stuff, I can't figure out how to send the appropriate messages to any solenoids past 15. So, I'm a little stuck here, any help?
I've attached the modified (and original) Solenoiduino stuff and a short video of what I have so far.
On Tue, 2013-09-10 at 01:53 -0400, Epic Jefferson wrote:
To control solenoids with dynamics, I adapted Reduzent's [Solenoiduino] abstraction and arduino sketch to include the TLC5940 functions, which is what the Practical Maker PWM shield is based on. So far, I'm able to control 44 solenoids using custom drivers and 2 stacked PWM shields. This is an excellent alternative if you want to build a relatively cheap electro-mechanical piano setup.
The problems i've run into: 1. if 2 or more messages get sent simultaneously, one of them might get dropped (this happens a lot)
This shouldn't happen and actually never happened in my own experience. A single 2-byte message sets and one pin to HIGH and sets a timer for that pin. So, if you need two set two pins simultaneously, you need to send two 2-byte messages. I don't see how the code could omit a message, unless two subsequent messages set the same pin.
If you modified the code, you can send me a copy, so I'll look into it.
1. the handshake does not seem to work on Linux (Ubuntu 11)
It's pretty crude. Whenever you send it a '255' (0xff) byte, it responds with the following ASCII sequence: 'SOL 0 1'. You can easily test that with [comport] directly.
The ugly thing is that [solenoiduino] has to make sure not to send any 0xff bytes and thus some values for periods are not allowed / replaced, e.g 127, 255, 383 etc.
1. the original code only supports 16 solenoids
This last one is the one that goes over my head, since the code uses that bit twiddling stuff, I can't figure out how to send the appropriate messages to any solenoids past 15. So, I'm a little stuck here, any help?
The solenoiduino code uses two bytes per message, while the first bit of each is used for defining the byte order. This leaves 14 bits for the payload. The current implementation uses 4 bits for the pin address and 10 bits for the duty cycle. If you can live with a lower duty cycle resolution, you can shift some bits around. For instance, you could adapt the bitmask to use 6 bits for the address (allows to control 64 solenoids) and use only 8 bit for the velocity / duty cycle.
Alternatively, you could extend the protocol to use 3 bytes per message. This would give you a payload of 21 bits to be distributed between address and duty cycle. Of course, this reduces your maximum message rate by 1.5.
Roman
The modified version of the arduino sketch is included in the .zip in my first email if you want to have a go at it. i haven't changed anything on the pd side. I would rather sacrifice duty cycle resolution and be able to control 64 solenoids, than making the entire message longer and slowing down the entire system.
As far as the dropped messages go, I'm sending separate messages by packing the data and sending it to a single [trigger $1 $2{ message box. I'll try sending separate messages to see if that helps.
On Tue, Sep 10, 2013 at 6:24 PM, Roman Haefeli reduzent@gmail.com wrote:
On Tue, 2013-09-10 at 01:53 -0400, Epic Jefferson wrote:
To control solenoids with dynamics, I adapted Reduzent's [Solenoiduino] abstraction and arduino sketch to include the TLC5940 functions, which is what the Practical Maker PWM shield is based on. So far, I'm able to control 44 solenoids using custom drivers and 2 stacked PWM shields. This is an excellent alternative if you want to build a relatively cheap electro-mechanical piano setup.
The problems i've run into: 1. if 2 or more messages get sent simultaneously, one of them might get dropped (this happens a lot)
This shouldn't happen and actually never happened in my own experience. A single 2-byte message sets and one pin to HIGH and sets a timer for
that pin. So, if you need two set two pins simultaneously, you need to
send two 2-byte messages. I don't see how the code could omit a message, unless two subsequent messages set the same pin.
If you modified the code, you can send me a copy, so I'll look into it.
1. the handshake does not seem to work on Linux (Ubuntu 11)
It's pretty crude. Whenever you send it a '255' (0xff) byte, it responds with the following ASCII sequence: 'SOL 0 1'. You can easily test that with [comport] directly.
The ugly thing is that [solenoiduino] has to make sure not to send any 0xff bytes and thus some values for periods are not allowed / replaced, e.g 127, 255, 383 etc.
1. the original code only supports 16 solenoids
This last one is the one that goes over my head, since the code uses that bit twiddling stuff, I can't figure out how to send the appropriate messages to any solenoids past 15. So, I'm a little stuck here, any help?
The solenoiduino code uses two bytes per message, while the first bit of each is used for defining the byte order. This leaves 14 bits for the payload. The current implementation uses 4 bits for the pin address and 10 bits for the duty cycle. If you can live with a lower duty cycle resolution, you can shift some bits around. For instance, you could adapt the bitmask to use 6 bits for the address (allows to control 64 solenoids) and use only 8 bit for the velocity / duty cycle.
Alternatively, you could extend the protocol to use 3 bytes per message. This would give you a payload of 21 bits to be distributed between address and duty cycle. Of course, this reduces your maximum message rate by 1.5.
Roman
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
On Tue, 2013-09-10 at 21:34 -0400, Epic Jefferson wrote:
The modified version of the arduino sketch is included in the .zip in my first email if you want to have a go at it. i haven't changed anything on the pd side. I would rather sacrifice duty cycle resolution and be able to control 64 solenoids, than making the entire message longer and slowing down the entire system.
I adapted the bitmask stuff in the the Pd patch and the Arduino sketch so that 6 bits are used for the pin address. This means, the velocity has now only 256 steps. Check the attachments.
Beware, I wasn't able to actually test the modifications as I currently don't have an arduino at hand.
As far as the dropped messages go, I'm sending separate messages by packing the data and sending it to a single [trigger $1 $2{ message box. I'll try sending separate messages to see if that helps.
I'm not totally sure if I understand you correctly, but this should be fine, as long as [solenoiduino] receives 'trigger X Y' messages.
The main difference between your version and mine is that yours uses the Tlc stuff. I don't know how this part behaves if you set and update twice in a row very quickly. May be this is the culprit? Just a guess, I can't test here and I don't have a clue what this code does or if it does something time critical at all. A cheap work-around might be to rate-limit the messages on the Pd side.
Regarding the handshake: You may skip that all-together if it doesn't work for you, as it isn't really necessary. I thought it might be a convenient way check to make sure the hardware has the correct firmware loaded. To quickly test send 255 to [comport] and see if you get something back. If so, the problem might be in the [solenoiduino] abstraction.
Roman
On Tue, Sep 10, 2013 at 6:24 PM, Roman Haefeli reduzent@gmail.com wrote: On Tue, 2013-09-10 at 01:53 -0400, Epic Jefferson wrote: > To control solenoids with dynamics, I adapted Reduzent's > [Solenoiduino] abstraction and arduino sketch to include the TLC5940 > functions, which is what the Practical Maker PWM shield is based on. > So far, I'm able to control 44 solenoids using custom drivers and 2 > stacked PWM shields. This is an excellent alternative if you want to > build a relatively cheap electro-mechanical piano setup. > > > The problems i've run into:
> 1. if 2 or more messages get sent simultaneously, one of them > might get dropped (this happens a lot) This shouldn't happen and actually never happened in my own experience. A single 2-byte message sets and one pin to HIGH and sets a timer for that pin. So, if you need two set two pins simultaneously, you need to send two 2-byte messages. I don't see how the code could omit a message, unless two subsequent messages set the same pin. If you modified the code, you can send me a copy, so I'll look into it. > 1. the handshake does not seem to work on Linux (Ubuntu 11) It's pretty crude. Whenever you send it a '255' (0xff) byte, it responds with the following ASCII sequence: 'SOL 0 1'. You can easily test that with [comport] directly. The ugly thing is that [solenoiduino] has to make sure not to send any 0xff bytes and thus some values for periods are not allowed / replaced, e.g 127, 255, 383 etc. > 1. the original code only supports 16 solenoids > This last one is the one that goes over my head, since the code uses > that bit twiddling stuff, I can't figure out how to send the > appropriate messages to any solenoids past 15. So, I'm a little stuck > here, any help? The solenoiduino code uses two bytes per message, while the first bit of each is used for defining the byte order. This leaves 14 bits for the payload. The current implementation uses 4 bits for the pin address and 10 bits for the duty cycle. If you can live with a lower duty cycle resolution, you can shift some bits around. For instance, you could adapt the bitmask to use 6 bits for the address (allows to control 64 solenoids) and use only 8 bit for the velocity / duty cycle. Alternatively, you could extend the protocol to use 3 bytes per message. This would give you a payload of 21 bits to be distributed between address and duty cycle. Of course, this reduces your maximum message rate by 1.5. Roman _______________________________________________ Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
-- www.epicjefferson.com www.avmachinists.org Puerto Rico based Art Collective/ Non-Profit Org
Awesome, thanks!
i tested it quickly and i can now address all of the solenoids from within pd.
On Wed, Sep 11, 2013 at 6:26 PM, Roman Haefeli reduzent@gmail.com wrote:
On Tue, 2013-09-10 at 21:34 -0400, Epic Jefferson wrote:
The modified version of the arduino sketch is included in the .zip in my first email if you want to have a go at it. i haven't changed anything on the pd side. I would rather sacrifice duty cycle resolution and be able to control 64 solenoids, than making the entire message longer and slowing down the entire system.
I adapted the bitmask stuff in the the Pd patch and the Arduino sketch so that 6 bits are used for the pin address. This means, the velocity has now only 256 steps. Check the attachments.
Beware, I wasn't able to actually test the modifications as I currently don't have an arduino at hand.
As far as the dropped messages go, I'm sending separate messages by packing the data and sending it to a single [trigger $1 $2{ message box. I'll try sending separate messages to see if that helps.
I'm not totally sure if I understand you correctly, but this should be fine, as long as [solenoiduino] receives 'trigger X Y' messages.
The main difference between your version and mine is that yours uses the Tlc stuff. I don't know how this part behaves if you set and update twice in a row very quickly. May be this is the culprit? Just a guess, I can't test here and I don't have a clue what this code does or if it does something time critical at all. A cheap work-around might be to rate-limit the messages on the Pd side.
I think it might be correct to assume that the dropped messages could be on the Tlc side of things, i have a feeling that while it's setting and updating, any incoming message could be lost.
Regarding the handshake: You may skip that all-together if it doesn't work for you, as it isn't really necessary. I thought it might be a convenient way check to make sure the hardware has the correct firmware loaded. To quickly test send 255 to [comport] and see if you get something back. If so, the problem might be in the [solenoiduino] abstraction.
this is a small problem, for some reason sending an 'open X' type message to solenoiduino doesn't bang the '255' message box. i have to click on it myself for it to work, wierd. Now that i think of it, the new max velocity is 255, is it possible the arduino could interpret this as trying to establish a connection again and not as the 'velocity' byte? I haven't noticed a problem but i haven't tested it properly yet. I might opt for removing the handshake entirely
Roman
On Tue, Sep 10, 2013 at 6:24 PM, Roman Haefeli reduzent@gmail.com wrote: On Tue, 2013-09-10 at 01:53 -0400, Epic Jefferson wrote: > To control solenoids with dynamics, I adapted Reduzent's > [Solenoiduino] abstraction and arduino sketch to include the TLC5940 > functions, which is what the Practical Maker PWM shield is based on. > So far, I'm able to control 44 solenoids using custom drivers and 2 > stacked PWM shields. This is an excellent alternative if you want to > build a relatively cheap electro-mechanical piano setup. > > > The problems i've run into:
> 1. if 2 or more messages get sent simultaneously, one of them > might get dropped (this happens a lot) This shouldn't happen and actually never happened in my own experience. A single 2-byte message sets and one pin to HIGH and sets a timer for that pin. So, if you need two set two pins simultaneously, you need to send two 2-byte messages. I don't see how the code could omit a message, unless two subsequent messages set the same pin. If you modified the code, you can send me a copy, so I'll look into it. > 1. the handshake does not seem to work on Linux (Ubuntu 11) It's pretty crude. Whenever you send it a '255' (0xff) byte, it responds with the following ASCII sequence: 'SOL 0 1'. You can easily test that with [comport] directly. The ugly thing is that [solenoiduino] has to make sure not to send any 0xff bytes and thus some values for periods are not allowed / replaced, e.g 127, 255, 383 etc. > 1. the original code only supports 16 solenoids > This last one is the one that goes over my head, since the code uses > that bit twiddling stuff, I can't figure out how to send the > appropriate messages to any solenoids past 15. So, I'm a little stuck > here, any help? The solenoiduino code uses two bytes per message, while the first bit of each is used for defining the byte order. This leaves 14 bits for the payload. The current implementation uses 4 bits for the pin address and 10 bits for the duty cycle. If you can live with a lower duty cycle resolution, you can shift some bits around. For instance, you could adapt the bitmask to use 6 bits for the address (allows to control 64 solenoids) and use only 8 bit for the velocity / duty cycle. Alternatively, you could extend the protocol to use 3 bytes per message. This would give you a payload of 21 bits to be distributed between address and duty cycle. Of course, this reduces your maximum message rate by 1.5. Roman _______________________________________________ Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
-- www.epicjefferson.com www.avmachinists.org Puerto Rico based Art Collective/ Non-Profit Org
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list