having trouble programming the solenoids

Hi again,

The solenoids work! The circuit provided was ok and works!

Now it's the programming that bugs me. I made a patch in max to control the solenoids but it's apparently waaaayy to slow to get it running (don't know why though, it shouldn't be)
I'm trying to program the solenoids in the arduino software.

What I'm trying to do is have a basic duration of a movement of the solenoid (which is just an adaptation of the blinking led thing with solenoid1 == HIGH and delay(24) solenoid1 == LOW and delay (38)) This loop has to be called until the basic duration (t1) is over. t1 is random(0.1-80)/10*60000 and needs to be called again when the last solenoid has finished it's cycle.

solenoid2 needs to begin somewhere during the second half of solenoid1's cycle and solenoid3 needs to begin somewhere in the cycle of solenoid2.

The whole movement of the solenoids doesn't need to start over again as soon as solenoid3 cycle is over but has to wait a random time between 1 and 5 minutes.

I have no id where to start here and would really be thankfull to anyone pointing me in the right direction. I know it's maybe a bit much to ask but I'm getting stressed since I need to have it finished next week.

pieter

While you are in a delay() loop you can't do anything else. You could put the switching of the solenoids in the loop() function. Measure time with millis(), when you are at the right time do something, switch solenoid on or off. Depending on what you want exactly you could use a switch/case statement. So, look up in the reference: millis and switch and see if it is of any use.

this may be the worst approach ever but is there a way that I can send a value from max to arduino like a specific number that triggers a loop that I already encoded on the board.
In that way I could write some loops in if statements that would control the three solenoids independitly and only have to send 4 diffrent numbers to arduino board which will be faster?

thx

pieter

You can send the numbers over the serial port. Reading and writing over the serial port is something you can find in the examples. But when you are in a delay() loop nothing else happens.

ok, I'm totally lost now.

the thing is it's not that I need to just turn the solenoid off and on I need to make them on-off-ing really fast. I looked at the millis() and switch case things and think this is the way to go. But I still have delays in my program because I don't understand how to do this diffrently. I know it won't work but I hope that by providing the code someone could see what exactly it is that I'm trying to do, I still can't have the speed I need from within max, which is very strange to say the least but that's another story.

I want to send a number from within max to arduino to adress the diffrent cases but also don't know how to change the var in the code from within max. I really don't find the reference or examples of great use, maybe I'm just too stupid?

ANyway hope someone can help me out here?

Thx

pieter

// I want to implement variable rates also that it isn't to mechanical but that's something else I don't understand
// Solenoid4 need to just have short HIGH and random long LOW hits from time to time,
int var;

int Solenoid1 = 13; // LED connected to digital pin 13
int Solenoid2 = 12;
int Solenoid3 = 11;

int Solenoid4 = 10;

int time;
long randNumber;
int time4;
long randNumber4;

void setup(){
var==0; // how can I change this from within max?
}

void loop(){
switch (1) {
case 1:
//solenoid 1 starts to vibrate and hits a large drum
digitalWrite(Solenoid1, HIGH); // sets the LED on
delay(24); // waits for a while
digitalWrite(Solenoid1, LOW); // sets the LED off
delay(38);
break;

case 2:
//solenoid 1 and 2 vibrate after some time
digitalWrite(Solenoid1,HIGH);
digitalWrite(Solenoid2,HIGH);
delay(24);
digitalWrite(Solenoid1,LOW);
digitalWrite(Solenoid2,LOW);
delay(38);
break;

case 3:
//solenoid 1, 2 and 3 vibrate

digitalWrite(Solenoid1,HIGH);
digitalWrite(Solenoid2,HIGH);
digitalWrite(Solenoid3, HIGH);
delay(24);
digitalWrite(Solenoid1,HIGH);
digitalWrite(Solenoid2,HIGH);
digitalWrite(Solenoid3,LOW);
delay(38);
break;

case 4:
// solenoid 2 and 3 vibrate
digitalWrite(Solenoid2,HIGH);
digitalWrite(Solenoid3,HIGH);
delay(24);
digitalWrite(Solenoid2,LOW);
digitalWrite(Solenoid3,LOW);
delay(38);
break;

case 5:
// solenoid3 vibrates
digitalWrite(Solenoid3, HIGH);
delay(24);
digitalWrite(Solenoid3,LOW);
delay(28);
break;

default:
// if nothing else matches, do the default
break;
}
}

the thing is it's not that I need to just turn the solenoid off and on I need to make them on-off-ing really fast.

Hi Pieter,

what do these solenoids look like? Do yo uhave a picture? If you want them to vibrate at 40hz this may be a physical impossibility... and en electrical one too. Physically, depending on how much mass these move and how far, 100ms is not going to be enought time for the solenoids to activate fully. Also, driving a solenoid at high speed may require a more complicated circuit.. as would driving any high-inductance circuit at high speed.

that's my 2ยข

D

I uploaded the blinking led sketch to the arduino board with diffrent intervals and tried it for 20 minutes and it works great, no problem with the intervals and arduino boars is working like a charm.

It's the interaction with max that doesnt work. And of course I just don't seem to grasp how to make the thing do what they should do.

It is possible I know this but to have S1 vabrite in a 24 on38 off pattern for 4 minutes and S2 start a minute after the S1 has started so that S1 stops when S2 is vibrating for 3 minutes and S3 doing a next fase in the sequence All this while S4 randomly hits the drum (with a 24ms On and at least a 5000s Off state) when S2 is On

that's what I don't know and apparently the comunication with max isn't fast enough or maybe I do something wrong?

thx in advance

pieter

Another script.

I've been rethinking everything and did some learning in processing to get the hang of the language and came up with the following script. But it doesn't seem to work, I still haven't included timer classes but think I made some counters to do things for me, could someone be so kind as to check the script and see where I made a mistake?

Best Regards,

Pieter

int solenoid1;
int solenoid2;
int solenoid3;
int solenoid4;

int s1;
int s2;
int s3;
int s4;

// counters macro
int c1;
int c2;
int c3;
int c4;

//ontime macro
int on1;
int on2;
int on3;
int on4;

//offtime macro
int off1;
int off2;
int off3;
int off4;

//micro Osc
int cm1;
int cm2;
int cm3;
int cm4;

int sm1; //status micro
int sm2;
int sm3;
int sm4;

int oscOn1;
int oscOn2;
int oscOn3;
int oscOn4;

int oscOff1;
int oscOff2;
int oscOff3;
int oscOff4;

void setup(){
// set pins
int solenoid1=13;
int solenoid2=12;
int solenoid3=11;
int solenoid4=10;

pinMode(solenoid1, OUTPUT);
pinMode(solenoid2, OUTPUT);
pinMode(solenoid3, OUTPUT);
pinMode(solenoid4, OUTPUT);

// status Solenoid (1=On 0=Off) macro
int s1=1;
int s2=0;
int s3=0;
int s4=0;

// counters macro
int c1=0;
int c2=0;
int c3=0;
int c4=0;

//ontime macro
int on1=5000;
int on2=180000;
int on3=180000;
int on4=180000;

//offtime macro
int off1=1000;
int off2=180000;
int off3=180000;
int off4=180000;

//micro Osc
int cm1=0;
int cm2=0;
int cm3=0;
int cm4=0;

int sm1=0; //status micro
int sm2=0;
int sm3=0;
int sm4=0;

int oscOn1=24;
int oscOn2=24;
int oscOn3=24;
int oscOn4=24;

int oscOff1=38;
int oscOff2=38;
int oscOff3=38;
int oscOff4=38;
}

void loop(){

c1 +=1;
if(s1=1){
if(c1=on1){
s1=0;
c1=0;
}
micro1(); // call micro1 function
}
if(s1=0){
if(c1=off1){
s1=1;
c1=0;
}
}
delay(1);
}

void micro1(){ // controls on off

if(sm1=1){
cm1 +=1;
if(cm1=oscOn1){
sm1=0;
cm1=0;
}
digitalWrite(solenoid1,HIGH);
}
if(sm1=0){
cm1 +=1;
if(cm1=oscOff1){
sm1=1;
cm1=0;
}
digitalWrite(solenoid1,LOW);
}
}

I did not study your code very carefully, but I did notice something that is most certainly not what you want. You declare global variables like:

int oscOn1;
int oscOn2;
int oscOn3;
int oscOn4;

Then, inside your setup() function, you declare other local variables that have the same name:

void setup()
{
// ....
int oscOn1=24;
int oscOn2=24;
int oscOn3=24;
int oscOn4=24;
}

Doing this has no effect, because those are local variables, meaning they cease to exist as soon as the setup() function returns. You should either remove the "int" so that you are no longer hiding the global variables with new local variables, like this:

void setup()
{
// ....
oscOn1=24;
oscOn2=24;
oscOn3=24;
oscOn4=24;
}

Or, even better in my opinion, go ahead and initialize your global variables at the same time you declare them:

int oscOn1=24;
int oscOn2=24;
int oscOn3=24;
int oscOn4=24;

void setup()
{
// ....
}

Hope this helps!

  • Don

Hi,

I stripped the code and tried all over again, mainly to understand what I'm doing. I have written the next code which should do it but I don't think the Cglobal is counting ok, because the solenoids keep working all the time and there isn't any interval. I guess the loop(of solenoids on and off) would take aprox. 4 minutes and the first aprox 1.5 min but it doesn't stop.

int Solenoid1 = 13; // LED connected to digital pin 13
int Solenoid2 = 12;
int Solenoid3 = 11;
int Solenoid4 = 10;
int c1 = 0;
int c2 = 0;
int c3 = 0;
int c4 = 0;
int state1=0;
int state2=0;
int state3=0;
int state4=0;
int Cglobal = 0;
int total=480000;

void setup()
{
pinMode(Solenoid1,OUTPUT); // sets the digital pin as output
pinMode(Solenoid2,OUTPUT);
pinMode(Solenoid3,OUTPUT);
pinMode(Solenoid4,OUTPUT);
}

void loop() { // great loop
if(Cglobal<=90000){
state1=1;
}
if(Cglobal>90000){
state1=0;
}
if(Cglobal<=60000 || Cglobal>=150000){
state2=0;
}
if(Cglobal>60000 && Cglobal< 150000){
state2=1;
}
if(Cglobal<=90000 || Cglobal>=180000){
state3=0;
}
if(Cglobal>90000 && Cglobal<180000){
state3=1;
}
if(Cglobal<=80000 || Cglobal>=120000){
state4=0;
}
if(Cglobal>80000 && Cglobal<120000){
state4=1;
}
if(Cglobal==total){ // reset functie na 4 minuten(tijd total)
Cglobal=0;
}
if(state1==1){
if(c1<24){
digitalWrite(Solenoid1, HIGH); // sets the LED on
}
if(c1>=24){
digitalWrite(Solenoid1,LOW);

}
if(c1==68){
c1=0;

}
c1 +=1;

}
else{
digitalWrite(Solenoid1,LOW);
}
if(state2==1){
if(c2<24){
digitalWrite(Solenoid2, HIGH); // sets the LED on
}
if(c2>=24){
digitalWrite(Solenoid2,LOW);

}
if(c2==68){
c2=0;

}
c2 +=1;
}
else{
digitalWrite(Solenoid2,LOW);
}
if(state3==1){
if(c3<24){
digitalWrite(Solenoid3, HIGH); // sets the LED on
}
if(c3>=24){
digitalWrite(Solenoid3,LOW);

}
if(c3==68){
c3=0;

}
c3 +=1;
}
else{
digitalWrite(Solenoid3,LOW);
}
if(state4==1){
if(c4<24){
digitalWrite(Solenoid4, HIGH);
}
if(c4>=24){
digitalWrite(Solenoid4,LOW);
}
if(c4==random(1000,5000)){
c4=0;
}
}

Cglobal +=1;
delay(1);
}

best
pieter