Message Boards Message Boards

Configuring Arduino Uno R3 board?

GROUPS:

Hi, I want to upload a basic sketch to Arduino Uno R3 board. This is the sketch:

int ON=500;

int OFF=500;

void setup() {

  pinMode(7,OUTPUT);

}

void loop() {

   digitalWrite(7, HIGH);

  delay(ON);

  digitalWrite(7, LOW);

  delay(OFF);

}

This is simple to do with the IDE but how can I do this with Mathematica?

I know the DeviceConfigure command will do it but I have difficulties to do it...

DeviceConfigure[arduino, "Upload" -> "BootFunction" -> <|"Code" -> {
      {"int", "ON" -> 500},
      {"int", "OFF" -> 500},
      {"void", "setup()"},
      {"pinMode(7,OUTPUT)"},
      {"void", "loop()"},
      {"digitalWrite(7,HIGH)"},
      {"delay(ON)"},
      {"digitalWrite(7,LOW)"},
      {"delay(OFF)"}
      }|>]

Thank you for your help.

Marcel Pelletier

POSTED BY: Marcel Pelletier
Answer
8 months ago

Hi Marcel,

The problem you're having here is that DeviceConfigure doesn't work exactly the way that you expect it to with the "Code" option. If what you are trying to do is create a blink function, the simplest way to do this is to use the built-in sketch that is already uploaded to the Arduino when you run DeviceOpen. This sketch allows for controlling the pins using functions like DeviceWrite and DeviceRead like the following:

val = 1;
Do[
    (DeviceWrite["Arduino",7->val];
    val = 1 - val;
    Pause[0.5]),
    {10}
]

Which will blink the LED attached to 7 5 times, with 500 milliseconds on and 500 milliseconds off.

Now, for completeness sake, while unfortunately you can't use the Mathematica IDE to upload arbitrary sketches, you can still use DeviceConfigure to configure the sketch that is uploaded to the Arduino manually to do the things you are doing the in above sketch. You can accomplish this through a couple different options to DeviceConfigure. The first is Initialization, which is basically any global block of C/C++ code you want to include in the sketch. We can use this for defining the variables ON, and OFF.

initCode = "int ON = 500, OFF  = 500;"

For code that we want to be run at boot time once and only once, we can like you have above use the "BootFunction" option. Here, like you have above, we only want to configure pin 7 as output.

bootFuncCode = "void bootFunc() { pinMode(7,OUTPUT); }"

For code that we want to run on a schedule, the built in sketch has a scheduler that allows for millisecond precision, so we can simply write a function that does whatever you want and upload it to the sketch with the "Functions" option. Then we can execute the function in whatever schedule we want with DeviceExecute..

blinkFuncCode = "void blinkFunc() { digitalWrite(7,HIGH); delay(ON); digitalWrite(7,LOW); delay(OFF); }"

We need to configure the sketch with all of this before executing anything:

DeviceConfigure["Arduino","Upload"->{
    Initialization->initCode,
    "BootFunction"-><|"Code"->bootFuncCode|>,
    "Functions"-><|"Blink"-><|"Code"->blinkFuncCode|>|>
}]

Now, to execute this once we can simply run:

DeviceExecute["Arduino","Blink"]

To run it as quickly as the scheduler allows, we can run:

DeviceExecute["Arduino","Blink","Scheduling"->0.001]

This effectively means that the sketch is now effectively running your blink function in an infinite loop. Of course we can stop it when we want with:

DeviceExecute["Arduino","DeleteTask","Blink"]

which stops the running task on the Arduino so we can do other things with it.

Also for completeness sake, it is generally easier to avoid any large delays in any code you want to configure the sketch with, and instead to use the scheduler to handle any delays you want. For example, here's another way to write the C code yourself, but still take advantage of the on board scheduler that runs independently of Mathematica on the Arduino.

DeviceConfigure["Arduino","Upload"->{
    Initialization->"int val = 0;",
    "Functions"-><|
        "BlinkInvert"-><|"Code"->"void blink() {pinMode(7,OUTPUT); digitalWrite(7,val); val = !val;}"|>,
        "BlinkArgument"-><|"Code"->"void blink(int pin, int val) {pinMode(pin,OUTPUT); digitalWrite(pin,val);}"|>
    |>
 }]

Now with the first one, we can simple call it on a schedule of 500 milliseconds and it will handle everything for us

DeviceExecute["Arduino","BlinkInvert","Scheduling"->0.5]

But if we'd rather blink it from the WL controlling the period with a slider, we can easily do that too with the following:

Manipulate[
    DeviceExecute["Arduino", "DeleteTask", "BlinkInvert"];
    DeviceExecute["Arduino", "BlinkInvert", "Scheduling" -> N@1/period],
    {period,1,1000}
]

Manipulate of period of blinking

Now we can control the period of the LED blinking dynamically with a slider!

If we wanted we can also make a simple button that only updates the period when we click the button

Column[
    {
        Slider[Dynamic[period], {1, 1000}], 
        Button["Update", (
            DeviceExecute["Arduino", "DeleteTask", "BlinkInvert"];DeviceExecute["Arduino", "BlinkInvert", "Scheduling" -> N@1/period]
        )]
    }
]

Manual updating with button and slider

Let me know if you have any questions about any of this code or other questions about using the Arduino driver in Mathematica.

Thanks,

Ian

POSTED BY: Ian Johnson
Answer
8 months ago

Hi Ian! Thank you for your help.. In fact, I have a second question to you.

I want to read the temperature "live" from the DHT11 with Mathematica. I also try to upload the Library for this but it is not working.

This is the code:

DeviceConfigure[arduino, "Upload" -> "Libraries" -> "dht.h"]

I know that the name is correct because in the IDE it is OK.
But this not working.

In the IDE, the code is

#include <dht.h>

dht DHT;

#define DHT11_PIN 8

void setup(){
 ...
  Serial.print("Temperature = ");
  Serial.println(DHT.temperature);
  Serial.print("Humidity = ");
  Serial.println(DHT.humidity);

I know now how to do (your first response). How can I configure the Library? Marcel

POSTED BY: Marcel Pelletier
Answer
8 months ago

Group Abstract Group Abstract