Arduino + Supercollider

Hi there.

I made this code to control multiple motors at the same time :

#define MAXTAILLE 50

int valMoteur1; // Status of the motor

class Timer{
public:
void start() {
t0 = millis();
t1 = t0;
}

void reset() { start(); }

int get_ms() {
t1 = millis();
return t1-t0;
}

float get_sec() {
return float(get_ms())/1000.0f;
}

private:
int t0, t1;
};  

class Sequencer{
public:
Timer timer;
float durations[MAXTAILLE];
int states[MAXTAILLE];
int index = 0;
int taille = 0;

void add(int stat, float durms) {
states[taille] = stat;
durations[taille] = durms;
taille++;
}

void start() {
timer.start();
}

bool check() {
if (timer.get_ms() >= durations[index]) {
index+=1;
if (index >= taille) index = 0;
timer.reset();
return true;
}
return false;
}
};

class Continu{
public:
String type = "continu";
int pin;
int state = 0; // arrêt
Sequencer seq;
String name;

Continu(String _name, int npin) {
name = _name;
pin = npin;
init();
}

void display() {
int newstate = seq.states[seq.index];
float dursec = seq.durations[seq.index]/1000.0f;
Serial.println(name);
Serial.println(int(newstate));
Serial.println(float(dursec));
//std::cout << "set state of " << name << " to " <<  state << " for " << dursec << " seconds" << std::endl;  
}

void start() {
seq.start();
display();
}

void check() {
if (seq.check()) {
set_state(seq.states[seq.index]);
display();
}
}

void init() {
pinMode(pin, OUTPUT);
}

void add(int stat, float dursec) {
seq.add(stat, dursec*1000.0f);
}

void set_state(int _state) {
state = _state;
Serial.println(state);

if (state == 0) digitalWrite(pin, LOW);
if (state == 1) digitalWrite(pin, HIGH);
}
};

Continu p1 = Continu("p1", 2);
Continu p2 = Continu("p2", 3);
Continu p3 = Continu("p3", 4);

void setup() {
Serial.begin(9600);

p1.add( valMoteur1 = 0, 2 );
p1.add( valMoteur1 = 1, 2 );
p1.start();

p2.add( 0, 2);
p2.add( 1, 2);
p2.start();

p3.add( 0, 2);
p3.add( 1, 2);
p3.start();

}

void loop() {

p1.check();
p2.check();
p3.check();
}

Everything works but now I would like to read the state of the motor in real time from Supercollider. To be clear I want to ask SuperCollider to do something if the motor is running and to stop when the motor stops.
I wrote this on SC to read from the Arduino USB port :

SerialPort.devices;
SerialPort.closeAll;
~port = SerialPort.new("dev/cu.usbmodemFA131",9600);
~port.read;

(
~charArray = [];
~getValue = Routine.new({
	var ascii;
	{
		ascii = ~port.read.asAscii;
		if(ascii.isDecDigit, {~charArray = ~charArray.add(ascii)});
		 if(ascii == $a, {~val = ~charArray.collect(_.digit).convertDigits;
		 	~charArray = [];
		 });
	}.loop;
}).play;
)

~val;

I'm not

a big user of Arduino, I just use it sometimes for some small projects, I'm more of a SC user so do you have any idea to help ?

Thanks for the work everyone put in this forum !
Have a good day.

Tanguyt

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

It is not clear to me where you are stuck

Hi,

Well I'll be in SC controlling arguments from multiple Synths depending of the state of each motor. The thing is I don't really know how to read and keep actualised those values from Arduino. Should I use digitalWrite & digitalRead at some point ? How do I read the three different values (from the three motors) independently ? Should I complete the code inside my 'check' function or in the loop ?

Thanks,

Tanguy

don't classes make the code soooo much easier to read

don't you need to monitor the Serial interface for commands to control the motors as well as query their state (what are the states (i.e. enum))?

does this code just toggle some pins at different intervals

// define Servos
// define servo positions

#define N   2

const unsigned long Interval [N] = { 500, 800 };
const byte          PinLed   [N] = { 13, 12 };

byte          state  [N];
unsigned long msecLst [N];

unsigned long msec;

// -----------------------------------------------------------------------------
void
chkPin (
    int  n )
{
    if ( (msec - msecLst [n]) >= Interval [n])  {
        msecLst [n] = msec;
        state [n] = ! state [n];
        digitalWrite (PinLed [n], state [n]);
        // write() servo: value based on state
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
    msec = millis ();

    for (unsigned n = 0; n < N; n++)
        chkPin (n);
}

// -----------------------------------------------------------------------------
void setup()
{
    Serial.begin(115200);
    Serial.println("SeveralThings-BlinkRedBlue-2");

    for (unsigned n = 0; n < N; n++)  {
        digitalWrite (PinLed [n], state [n]);
        pinMode      (PinLed [n], OUTPUT);
        // attach servos
    }
}

The giant machine buried under Switzerland?

2 Likes

looks like https://supercollider.github.io is similar to Arduino or https://processing.org which can interact with an Arduino to do "physical computing" as described in What is Arduino?

The result is quite simple, I'm in this case controlling 3 DC motors wired with mosfets. I wrote this code a few years ago for an installation driving 9 motors, I haven't code in Arduino or C since.

The void setup is just filled with values in seconds to give informations to the motors :

p1.add( valMoteur1 = 0, 2 ); // stop the motor for 2 sec
p1.add( valMoteur1 = 1, 10 ); // start the motor for 10 sec
p1.add( valMoteur1 = 0, 10 ); // stop the motor for 10 sec etcetcetc....
p1.start();

p2.add( 0, 2);
p2.add( 1, 2);
p2.start();

p3.add( 0, 2);
p3.add( 1, 2);
p3.start();

I wrote this to be able to easely control the multiple motors at the same time. The check function just verify the state of the motor accordingly to the timer set when the board gets switch on.

I assume this wasn't the prettiest way to do it but this is how I dit it at the time...

You think I should rewrite everything ?

Thx,

Tanguy

you should do what you feel comfortable with. when code is reviewed professionally, it needs to use approaches that are familiar to those reviewing the code and who may need to maintain it in the future

for such a small program, i question whether explicit classes makes it easier to understand. (is there need for more than one)? just using classes doesn't make it OOD.

i copied the code i posted from another thread, cutting the OP's code size in half and showing how the code could be simpler.

where each object requires different parameters, i typically define a struct and statically initialize an array of structs. each line specifies the parameter. adding an additional object is just a single line in the code.

of course there are functions to operate on the struct (i.e. methods).

you now need to add code to read serial input, interpret it and generate a response