Millumin & Arduino - Millumin Stream

Hey guys, 

Im brand new to Millumin but got told about it when discussing a project with a friend, and it turns out its exactly what I was looking for.  I have managed to get a rudimental version of what I am trying to achieve to work. But now i'm trying to slim-line it a little bit and was hoping for a couple of pointers.

* I must also add that i'm pretty new to Arduino too, but picking it up very quickly.

So my project is an installation, of witch we project onto box's the box's have a motor in each to rotate them.  Millumin triggers the motor to go and plays the video to animate the box spinning.  

I have got to a point where Millumin sends a HIGH value on D5, witch goes though a resistor to D4, D4 is setup to listen for HIGH, when it see's it, it triggers the motor (the amount of steps is all fixed inside the Arduino code, so just need a trigger). 

Thats fine I can keep working like that, but when I start running 4 motors off of each Arduino its just more cables and bits in the circuit.  So I am wondering how I can pass a value though Milluminstream to trigger different motors.  I have followed the online examples but im getting a little bit stumped.  I also could be completely wrong on how I understand the Milluminstream library to work.

From what im understanding from it onInPutvalue I can get the Key:Index & value being sent.  So in Millumin I tell an electronic layer to send 
"M1 1" I should receive that in the variable in my Arduino? (I am using M to represent Motor, so M2 would be the second Arduino controlling the second stack of box's).

My code in Arduino inside the "void onInputValue(uint8_t key, uint8_t index, uint16_t value)" would see if its an 'M' key and Index, then depending on the number that is passed in the value, trigger that motor.  So 0 would keep all off, 1 would trigger the sequence for motor 1 and so on.

Am I right in thinking like this? Does this even make sense? I was having troubles with getting the info passed.  Do I need togo into an Analog I/O to read the value if I send it out a digital pin instead of it doing it internally?

Any advice or points in the right direction would be grand.

many thanks
Tuck

Comments

  • Hello @tucklx,

    The simpler way to do what you are trying is to use the auto-program tool from Millumin. In your case, you just have to create one output per motor you have. Then, use a datatrack to directly the correct value to your motor. More info about the auto-program here.

    Auto-program is easy to use, but it is'nt the most optimized things. If you want to do something more complex, you have to use the MilluminStream library.
    Here is an example that listen for the key M1, and write the received value to D8 :

    #include <Arduino.h>
    #include <MilluminStream.h>

    // This the the input callback function
    // MilluminStream automatically handle A and D key value
    // A is for analogic input
    // D is for digital input
    // Other key are handle in this method
    void onInputValue(uint8_t key, uint8_t index, uint16_t value)
    {
      if( key == 'M' )
      {
        if( index == 1 )
        {
          digitalWrite(8, value); // write value to the pin D8
        }
        // TODO : handle other index
      }
      // TODO : handle other key ?
    }



    ////////////////////////////////////////////////////////////////////////////////
    // Initialisation
    void setup()
    {
      // We setup MilluminStream
      MilluminStream::setup();

      // We set the callback. We will use it to get custom event from Millumin
      MilluminStream::setInputCallback(onInputValue);

      // We initialise each pin we need to use
      pinMode(8, OUTPUT); // pin D8 is OUTPUT because we want to write in it
    }



    ////////////////////////////////////////////////////////////////////////////////
    // Loop
    void loop()
    {
      // First, we need to update MilluminStream
      MilluminStream::update();

      // Finally we send just one frame with all our values
      MilluminStream::sendFrame();
    }


    This example is only interesting because it show you the logic of the programmation with MilluminStream. But what it does could exactly be done by using the auto-program to write directly to the pin D8. Using MilluminStream could be interesting if you need to have a more complex comportment in "void onInputValue(uint8_t key, uint8_t index, uint16_t value)".

    Don't hesitate to look at our dev-kit to have more example.

    Does this solve your problem ?

    Sincerely your,
    Nicolas
  • Hey Nicolas, 

    Thanks for your help on this!  I had a play with the auto-programming functions but found that I needed more control over the steppers, but that all makes sense!  Instead of passing the value to D8 could i store it in a var then use it to call witch motor it is. maybe some thing like ;

    void onInputValue(uint8_t key, uint8_t index, uint16_t value)
    {
     if (key == "M")
     {
      if (index == 1)
      Milumsel = value;
     }

    And then in loop I can check witch motor as been asked to move and send it the correct amount of steps for that sequence?  

    if (Milumsel >> 0)
    {
     if (Milumsel == 1)
     {
      motor1.step(stepsPerRevolution);
      delay(1000);
      }
       if (Milumsel == 2)
     {
      motor2.step(stepsPerRevolution);
      delay(1000);
      }
       if (Milumsel == 3)
     {
      motor3.step(stepsPerRevolution);
      delay(1000);
      }
    } if (Milumsel == 4)
     {
      motor4.step(stepsPerRevolution);
      delay(1000);
      }

    I have been looking thought the Dev kit taking bits and trying things but as I'm quite a beginner at Arduino Programming im not quite grasping what some if means.  Though this clears things up thanks!

    Best
    Tuck
  • Hello @tucklx,

    Yes, you can do it. Since you declare your variable Milumsel, you can stock a value inside. In your example, I don't see where you declare it, but I assume it's a static variable.
    Anyway, for what I understand of your example, if Millumin send the value 1 on the key M1, the motor 1 will move as long as Millumin doesn't send the value 0. If this is what you want, I don't see any problem. Now, the best way to know if that work is to test it :)

    Let me know if you have any problem.

    Sincerely your,
    Nicolas
  • Evening Nicolas, 

    So I have set up up but can't get it to pass the value through, if it is passing any thing though.  So I am a little stumped.  I had it working when I told Millumin to turn on D6 and then Arduino listened for it on D7 and then triggered the motors, but I can't get it to pass the value thought.  Can you seen any rookie errors in my code? Been over it a few times but getting stumped on it now.

    It also works perfectly driving D13 on its own.

    #include <Stepper.h>

    #include <LiquidCrystal.h>

    #include <MilluminStream.h>
    //Motor Setup Vars;
    const int stepsPerRevolution = 2048;  
    int rotationsToTake = 0;
    int motorSel = 0;
    int Milumsel = 0;

    // initialize the library for motors & LCD screen:
      Stepper motor1(stepsPerRevolution, 11, 9, 10, 8);
      Stepper motor2(stepsPerRevolution, 7, 3, 6, 2);
      Stepper motor3(stepsPerRevolution, 30, 31, 32, 33);
      Stepper motor4(stepsPerRevolution, 34, 35, 36, 37);

    //////////////////////////////////////////////////////////////////////////////////

    void onInputValue(uint8_t key, uint8_t index, uint16_t value)
    {
     if (key == "M")
     {
      if (index == 1)
      Milumsel = value;
     }
    }

    //////////////////////////////////////////////////////////////////////////////////

    void setup() 
    {
    // We setup MilluminStream
      MilluminStream::setup();
      MilluminStream::setInputCallback(onInputValue); 
    // set up the LCD
    //  lcd.begin(16, 2);
    //  lcd.print("What Your Fed");
    //Set up the Motors;
      motor1.setSpeed(5);
      motor2.setSpeed(5);
      motor3.setSpeed(5);
      motor4.setSpeed(5);
    //Setup any other Pins
     pinMode(13, OUTPUT); //to test Millumin is passing some data 
    }

    //////////////////////////////////////////////////////////////////////////////////
    void loop()
    {
    //Check if there is a signle from Millumin;
     MilluminStream::update();
     if (Milumsel >> 0)
    {
     if (Milumsel == 1)
     {
      motor1.step(stepsPerRevolution);
      delay(1000);
      }
       if (Milumsel == 2)
     {
      motor2.step(stepsPerRevolution);
      delay(1000);
      }
       if (Milumsel == 3)
     {
      motor3.step(stepsPerRevolution);
      delay(1000);
      }
    } if (Milumsel == 4)
     {
      motor4.step(stepsPerRevolution);
      delay(1000);
      }
       // Finally we send just one frame with all our values
      MilluminStream::sendFrame();
    }

    Many thanks

    Tuck
  • Hello @tucklx,

    The best thing to do to debug a sketch that dosn't work is to add some :
    digitalWrite(13, HIGH);
    delay(1000);
    digitalWrite(13, LOW);
    in
    your code. Those lines while blink a led on your arduino when they are
    called. So, you can add those lines in your code to know which part of
    your code are executed or not.

    Doing so, I discover that this was never executed, at line 22 :
    if (key == "M")
     {
      if (index == 1)
      Milumsel = value;
     }
    Indeed,
    your "rookie error" is that you write "M" instead of 'M'. The " is used
    for string and ' for character. In this case, you are trying to test
    for a character, so you have to use '.

    Another little error line 70, but not important at all :
    } if (Milumsel == 4)
    I think you want this condition to be inside the big condition line 53 :
    if (Milumsel >> 0)
    But your "if" is out of this scope.

    Did that solve your problem ?

    Sincerely your,
    Nicolas
  • Nicolas, Thank you for all your help!  The 'M' solved my problems, and thank you for pointing out the 4th motor problem.  I managed to test it today and get Millumin to trigger what I needed!! So thank you very much!

    Thanks for all your help!

    Best
    Tuck
Sign In or Register to comment.