arduino, AZ3166, IOT, MXChip

Hacking with the MXChip AZ3166 Azure DevKit – a better PWM implementation

This is another post about the AZ3166 MXChip DevKit – this post builds on part 4 of my getting started series, and describes another way to implement pulse-width-modulation (PWM) in code.

You might wonder why I’m spending so much time with servos and this device – my personal use-case is that I’d like to use the sensors on the device alter something in the physical world – to use a classic example, when the temperature falls below a certain value, I’d like to use a servo to change the position of a thermostat.

Recap

I normally use PWM for controlling servos where I’ve not been able to use a pre-packaged library (like the one that ships with the Arduino IDE). That package doesn’t work with the AZ3166 hardware, so in a previous post I described how to use PWM and the Arduino function analogWrite to control a servo position.

The code below describes how to control a servo by sending a PWM signal to the PWM_OUT pin, and allowing 1s for the wiper to reach its final position.

#define analogIn A2
 
int inputValue = 0;
 
void setup() 
{
}
 
void loop() 
{
  for (int i = 5; i < 31; i++)
  {
    analogWrite(PWM_OUT, i);
    inputValue = analogRead(analogIn);
    delay(1000);
  }
}

My servo is a little bit special in that it has an extra pin that allows me to measure an analog value corresponding to the wiper position between 0 and 180, so I’m able to graph the position against the value that I pass to analogWrite.

The graph below shows the position of the servo against the value passed to analogWrite.

Analog Feedback servo - AZ3166 - input vs angle

I found a couple of things which were a bit odd:

  • The documentation for the device says I can control PWM through three pins corresponding to RGB_R, RGB_G, RGB_B – but I could only issue a PWM signal using analogWrite through physical pin 7 (corresponding to the software pin PWM_OUT). I could physically observe this PWM through the servo, and also through the green LED, but I couldn’t replicate this with the red or blue LEDs or their pins.
  • I can control the position of the servo by changing what value I pass to the analogWrite function – however, through a process of trial and error, I found that even though I can pass integers between 0 and 255 to analogWrite, the only values which allow me to control the servo position are between 5 and 31. Given there’s 180 degrees in a full servo sweep, that means I don’t have very much control over the servo’s angular position using analogWrite and the AZ3166. Also, guessing/trial and error isn’t a great way to achieve repeatable control.

Since writing that post, I’ve found a different way of controlling servos. The AZ3166 uses the MBED microcontroller library, mbed.h, which refers to another useful library, PwmOut.h.

I found the code for mbed.h on my machine at:

C:\Users\jeremy\AppData\Local\Arduino15\packages\AZ3166\hardware\stm32f4\1.2.0\cores\arduino\system\mbed.h

Also the code for PwmOut.h is on my machine at:

C:\Users\jez_l\AppData\Local\Arduino15\packages\AZ3166\hardware\stm32f4\1.2.0\system\drivers\PwmOut.h

How to use the PwmOut.h functions to create and control a PWM signal

I found the comment by Arthur Ma on Github very helpful when writing this post.

So let’s say I wanted to instantiate one of the three pins available for PWM use – let’s choose PB4, which is shared with the red onboard LED, RGB_R – I could declare it in my arduino code in this way.

PwmOut myServoPin(RGB_R);

which is equivalent to:

PwmOut myServoPin(PB_4);

This just says “make pin PB_4 available to send a PWM signal”.

The next bit is really useful – I can control the frequency and period of the PWM signal using the functions available in the PwmOut.h library. So if I wanted my pin’s PWM signal to have a frequency of 50Hz, i.e. a period of 20ms (because 1/50 = 0.02), I could send the instruction:

myServoPin.period_ms(20.0f)

The servo’s position is determined by the width of the pulse sent each cycle, and typically a pulse width of 1.5ms will turn the servo to its central (90 degree) position. So if I wanted to do this, I could send the instruction

myServoPin.pulsewidth_us(1500);

1500 microseconds is the same as 1.5ms. The function pulsewidth_us allows me to set the width in microseconds, and pulsewidth_ms allows me to set it in milliseconds.

I wrote the program below and uploaded it to my AZ3166 to see how the analog signal varied with pulse width, and found I can control the position of the wiper much more accurately now, and I can control it on any of Pins 5, 7, and 10 (corresponding to RGB_R, RGB_G, and RGB_B).

#define analogIn A2
 
PwmOut myServoPin(RGB_R);
 
void setup()
{
}
 
void loop()
{
  myServoPin.period_ms(20.0f);
  
  for (int i = 1; i < 3000; i++)
  {
    myServoPin.pulsewidth_us(i);
    delay(50);
  }
}

I’ve included the graph of results below.

Analog Feedback servo - AZ3166 - input vs angle - using PwmOut

There are some limitations of the cheap hobby servo which are now obvious.

  • You can see that the servo only reliably sweeps between pulse-width values of about 690 and 2270.
  • The servo jumps from 0 degrees to about a 40 degree position at a pulse width of 253microseconds, after which there is a very linear relationship.
  • The servo output reports a higher than expected value quite often, as shown by the data points above the main trend line – with this knowledge, I can anticipate this behaviour and code for it.

Wrapping up

I’ve discovered a better way of controlling pulse-width-modulation signals on the AZ3166 device using PwmOut – previously I used analogWrite with a single pin, and now I can use three pins, and control the period and pulse width to much higher degree of accuracy.

 

arduino, AZ3166, IOT, MXChip

Using the MXChip AZ3166 Azure DevKit with Arduino – coding with pin names instead of numbers

This post is part of my series on the MXChip AZ3166 DevKit – the device has lots of built in sensors, but this series focusses on interactions with external devices through the physical pins on the edge connector.

Part 1: Getting started

Part 2: Mapping virtual Arduino pins to physical digital I/O pins

Part 3: Reading analog values through physical pins

Part 4: Pulse-width modulation and servos

I own a couple of edge connector breakout boards – one from Kitronik, shown below..

Kitronik Edge Connectors

…and the other is from Sparkfun, shown below.

Sparkfun Edge Connectors

In part 2, I looked at how the physical pins on the edge connector mapped to numbers that I could use in my Arduino code. But I wasn’t really happy with this – it seemed a little unintuitive to access a green LED through the (seemingly arbitrary) virtual pin number 19.

Fortunately I’ve found a better solution. After some hunting through the source code, I’ve discovered a file named PinNames.h. This file is buried way way way down in the bowels of my computer – it’s located on my machine at the directory below:

C:\Users\jez_l\AppData\Local\Arduino15\packages\AZ3166\hardware\stm32f4\1.2.0\system\targets\TARGET_MXCHIP\TARGET_AZ3166

And this file provided me with the solution to my problem – I was able to find all the reserved variable names corresponding to pins and features on-board the AZ3166.

So instead of having to access the green LED through pin 19, instead I can access it through the alias RGB_G which the Arduino IDE already knows about.

And if I’m using it to produce a PWM signal, I can access it through PWM_OUT – which makes a lot of sense too.

From analysing the PinNames.h file, I’ve gathered these aliases together into a single image, shown below. This shows the aliases in the column named “Reserved Arduino variable name” below.

AZ3166 Edge Connector with Arduino AliasesAs well as naming all the LED pins, this matrix makes it clear that there are:

  • 2 analog pins (PA4 and PA5),
  • 11 digital pins (PB3, PB6, PC13, PB10, PB2, PB7, PB13, PB14, PB15, PB8, PB9),
  • I2C pins (PB8 and PB9),
  • SPI pins (PB13, PB14, and PB15),
  • 2 button pins (PA4 and PA10), and
  • 1 PWM pin (PB3).

How is this useful?

Previously, if I’d wanted to turn on the user LED on my AZ3166, I could have written code like this:

int USER_LED = 45;
 
void setup() 
{
  pinMode(USER_LED, OUTPUT);
}
 
void loop() 
{
  digitalWrite(USER_LED, HIGH);
}

I’ve declared the USER_LED as 45, but it’s a bit weird – someone coming to the code will maybe wonder why I’ve used this number when there’s not 45 pins on the edge connector.

But now if I want to turn on the user LED on my AZ3166, I can write code like:

void setup() 
{
  pinMode(LED_USER, OUTPUT);
}
 
void loop() 
{
  digitalWrite(LED_USER, HIGH);
}

Because the variable LED_USER isn’t declared in the code, it’s more obvious that it’s a reserved Arduino variable, and the number 45 isn’t thrown into the mix to add unnecessary cruft to the code.

Now I have a nice (and supported) way to clearly identify intent in my code, and I just need to make sure that I hook the right pin up to any external device (using my table above).

Yes – it’s just one less line! But it all counts towards cleaner and more standard code. I’ll be using this matrix in future to make my device code better.

.net core, Cake, IOT, nuget, Raspberry Pi 3

Deploying a .NET Core 2 app to a Raspberry Pi with Cake and PuTTY saved sessions

I’ve written previously about creating a .NET Core 2 template for a simple IoT application which can be deployed to the Raspberry Pi. Recently I was asked if this could be extended to use PuTTY saved sessions, which I thought was an interesting challenge.

I’ve used Cake to help me deploy my .NET Core 2 code – you can see the build.cake file up on GitHub for my template – and this script uses an add-in called Cake.PuTTY to allow me to deploy cross platform .NET Code from my Windows development machine to the Linux based Raspbian Jessie system running on my Raspberry Pi.

I’ve always just supplied my Raspberry Pi’s IP address and username through configurable parameters in the build.cake script, as shown below.

///////////////////////////////////////////////////////////////////////
// ARGUMENTS (WITH DEFAULT PARAMETERS FOR LINUX (Ubuntu 16.04, Raspbian Jessie, etc)
///////////////////////////////////////////////////////////////////////
var runtime = Argument("runtime""linux-arm");
var destinationIp = Argument("destinationPi""192.168.1.73");
var destinationDirectory = Argument("destinationDirectory"@"/home/pi/DotNetConsoleApps/RaspbianTest");
var username = Argument("username""pi");
var executableName = Argument("executableName""HelloRaspbian");

And these are used in the Cake build script in the “Deploy” target – I’ve pasted a snippet of code below which does a few things I’ve listed below the code:

var destination = destinationIp + ":" + destinationDirectory;
var fileArray = files.Select(m => m.ToString()).ToArray();
Pscp(fileArray, destination, new PscpSettings
                                    { 
                                        SshVersion = SshVersion.V2, 
                                        User = username 
                                    }
);
 
var plinkCommand = "chmod u+x,o+x " + destinationDirectory + "/" + executableName;
Plink(username + "@" + destination, plinkCommand);
  • First, it uses the PSCP function (which securely copies files) and supplies the destination in the format of an IP address, then a colon, then the directory that I want to copy files to on the remote machine – as shown below:
"192.168.1.73:/home/pi/DotNetConsoleApps/RaspbianTest"
  • The snippet also supplies the username “pi” to the PSCP function – I supplied this username in the configurable parameter section described earlier.
  • Finally it uses the Plink function to run a custom linux command on remote files – in this case, I change the permissions of the file I need to run to make it executable. Again, here I need to specify a username, and IP address and a location in the format below:
"pi@192.168.1.73:/home/pi/DotNetConsoleApps/RaspbianTest"

So my existing mechanism to deploy a file is really tightly coupled to knowing the username and the destination IP address in the code.

Can we do better with a saved PuTTY session?

I plugged my IP address and username into PuTTY, and saved them as a session named “Raspbian”. I’ve included a couple of screenshots below showing where I entered key bits of data. The first one shows the IP address, and where I name the saved session as “Raspbian”.

Putty saved session with IP address

The second one shows where I enter the username that I’d like to log on with:

Putty saved session with username

Once this “Raspbian” session was saved, I needed to find out how to use it with PSCP and Plink tools.

Using PSCP with Cake.PuTTY

This turned out to be pretty easy – instead of passing the destination IP address, I just passed in the session name. So now instead of:

"192.168.1.73:/home/pi/DotNetConsoleApps/RaspbianTest"

I’ve got:

"Raspbian:/home/pi/DotNetConsoleApps/RaspbianTest"

And I don’t need to pass the username in the settings anymore, so my code in the Cake build script for PSCP looks like this:

var destination = sessionname + ":" + destinationDirectory;
var fileArray = files.Select(m => @"""" + m.ToString() + @"""").ToArray();
Pscp(fileArray, destination, new PscpSettings
                                    { 
                                        SshVersion = SshVersion.V2 
                                    }
);

Using Plink

This turned out to be a little harder – but not too much. I couldn’t get the Cake.PuTTY plugin to work for this, but fortunately I’m able to use the StartProcess C# method with Cake to just run a Plink command.

The command I’d like to run looks like:

plink -load Raspbian [[insert a custom linux command here]]

And the C# code for this, where sessionname = “Raspbian”, is pasted below:

var plinkCommand = "chmod u+x,o+x " + destinationDirectory + "/" + executableName;
 
StartProcess("plink"new ProcessSettings {
        Arguments = new ProcessArgumentBuilder()
            .Append(@"-load")
	    .Append(sessionname)
            .Append(plinkCommand)
        }
);

So now that I can deploy with a saved session, I create a new configurable parameter in my build.cake script called “sessionname”, and leave the username and IP address fields blank.

///////////////////////////////////////////////////////////////////////
// ARGUMENTS (WITH DEFAULT PARAMETERS FOR LINUX (Ubuntu 16.04, Raspbian Jessie, etc)
///////////////////////////////////////////////////////////////////////
var runtime = Argument("runtime""linux-arm");
var destinationIp = Argument("destinationPi""<<safe to leave blank>>");
var destinationDirectory = Argument("destinationDirectory"@"/home/pi/DotNetConsoleApps/RaspbianTest");
var username = Argument("username""<<safe to leave blank>>");
var sessionname = Argument("sessionname""Raspbian");
var executableName = Argument("executableName""HelloRaspbian");

And use the target “DeployWithPuTTYSession”, which is detailed below:

Task("DeployWithPuTTYSession")
    .IsDependentOn("Publish")
    .Does(() =>
    {
        var files = GetFiles("./publish/*");
        
		var destination = sessionname + ":" + destinationDirectory;
		var fileArray = files.Select(m => @"""" + m.ToString() + @"""").ToArray();
		Pscp(fileArray, destination, new PscpSettings
					{ 
						SshVersion = SshVersion.V2 
					}
		);
 
		var plinkCommand = "chmod u+x,o+x " + destinationDirectory + "/" + executableName;
 
		StartProcess("plink"new ProcessSettings {
        		Arguments = new ProcessArgumentBuilder()
            		.Append(@"-load")
			.Append(sessionname)
            		.Append(plinkCommand)
        }
);

Updating the open source code, and how to use it

I’ve updated the source code on Github and also updated the NuGet package – you can check out my previous post on how to install this .NET Core template, and there are instructions on the project ReadMe, but the short version is that you can run the command below at a command prompt:

 dotnet new -i RaspberryPi.Template::*

And then you can create a new RaspberryPi IoT project (I called mine HelloRaspbian, yours can obviously be different) with the command:

dotnet new coreiot -n HelloRaspbian

From the generated project, run the command in the ReadMe.txt file to generate a build.ps1 file so we can run Cake:

Invoke-WebRequest http://cakebuild.net/download/bootstrapper/windows -OutFile build.ps1

Now open the build.cake file and update the parameters you want to use – the focus of this post is on a PuTTY session, and now we can update the sessionname parameter. Then in the project folder, run the command:

.\build.ps1 -target DeployWithPuTTYSession

This command will use your saved PuTTY session when deploying from a Windows machine to a Raspberry Pi running Linux, and allow you to deploy without specifying a username or IP address in your build.cake file.

Wrapping up

I’ve extended my RaspberryPi.Template for .NET Core to allow users to deploy to their Pi using a saved PuTTY session. Hopefully this small extension makes the template easier for the community to use.

arduino, AZ3166, MXChip

Using the MXChip AZ3166 Azure DevKit with Arduino – pulse-width modulation and servos

This post is part of my series on the MXChip AZ3166 DevKit – the device has lots of built in sensors, but this series focusses on interactions with external devices through the physical pins on the edge connector.

Part 1: Programming the MXChip AZ3166 Azure DevKit – getting started

Part 2: Programming the MXChip AZ3166 Azure DevKit – mapping virtual Arduino pins to physical digital I/O pins

Part 3: Programming the MXChip AZ3166 Azure DevKit – reading analog values through physical pins

Another feature of the AZ3166 is its ability to output pulse-width modulated (PWM) signals. In each period, a PWM signal spends some time “on” and some time “off”. The fraction of time spent on in relation to off is known as the duty-cycle. This concept is particularly useful to control servos, as varying the duty-cycle allows us to control the angular position of the servo wiper.

Testing with on-board devices – using PWM to make the green LED glow brighter and dimmer

We can use the analogWrite function with physical pin PB3 (physical pin 7;Arduino virtual pin 19) to write a PWM signal – this pin is shared with the on-board green LED, so even without an external device, we can see the PWM make the green LED glow brighter and dimmer with the sketch below.

The sketch also writes the PWM values to the on-board OLED display.

int GREEN_PWM_PIN_PB3 = 19; 
 
void setup() 
{
 
}
 
void loop() 
{  
  for (int i = 1; i < 50; i++)
  {
    analogWrite(GREEN_PWM_PIN_PB3, i);
 
    Screen.print("PWM Value:", false);
    char buf[10];
    sprintf(buf, "%d", i);
    Screen.print(1, buf);
  }
 
  for (int i = 50; i > 1; i--)
  {
    analogWrite(GREEN_PWM_PIN_PB3, i);
 
    Screen.print("PWM Value:", false);
    char buf[10];
    sprintf(buf, "%d", i);
    Screen.print(1, buf);
  }
}

The MXChip documentation suggests that there’s actually three PWM pins – PB4 (the red LED) and PC7 (the blue LED). However I’ve not been able to prove these work on my board.

Using PWM with a servo

I mainly use PWM for controlling servos – there’s already a great library for the Arduino and servos – check out the example here – but this doesn’t work with the MXChip AZ3166.

At the time of writing, when I try to use the servo example with the AZ3166, I get the error message:

WARNING: library Servo claims to run on [avr architecture(s) and may be incompatible with your current board which runs on sam architecture(s).
#error "This library only supports boards with an AVR, SAM or SAMD processor."
exit status 1
Error compiling for board MXCHIP AZ3166.

So to get a servo working, it looked like I was going to have to directly use PWM from the AZ3166.

Unfortunately, I don’t know what the PWM pulse frequency of the AZ3166, so I can’t calculate what PWM value that I need to set in the AnalogWrite function (from 0 to 255) to Pin 7. However, I can carry out a few experiments with a servo which has analog feedback.

Normal cheap servos just receive a signal to move from a controller, and the wiper sweeps to a certain angular position, without any feedback supplied to the controller regarding whereabouts the position of the wiper. However, some servos have a means to measure the wiper’s position (usually with a potentiometer) by sending an analog voltage signal back to the controller.

I wrote a sketch (pasted below) to vary the PWM value and send to a servo. With my servo with analog feedback, I can use the analogRead function to see how the output varies with the PWM values. After some experimentation, I found that varying the PWM values between 7 and 30 swept the wiper between its minimum and maximum positions. Sending PWM values outside of this range didn’t make the wiper move.

#include <OledDisplay.h>
 
int pwmPin = 19;
int analogIn = 4;
int inputValue = 0;
 
void setup() {
	Serial.begin(9600);
	Screen.init();
}
 
void loop() {
	for (int i = 5; i < 31; i++)
	{
		analogWrite(pwmPin, i);
 
		inputValue = analogRead(analogIn);
 
		Serial.print("PWM = ");
		Serial.print(i);
		Serial.print(": Analog In = ");
		Serial.println(inputValue);
 
		Screen.print("PWM Value:", false);
		char buf[10];
		sprintf(buf, "%d", i);
		Screen.print(1, buf);
 
		sprintf(buf, "%d", inputValue);
		Screen.print(2, buf);
 
		delay(1000);
	}
}

I plotted the results (shown below).

Analog Feedback servo - AZ3166 - input vs angle

Wrapping up

The MXChip AZ3166 sends a PWM signal through pin 7 (Arduino virtual pin 19). This pin is connected to the green LED on board, and we can use PWM to adjust the brightness of this LED. I’ve also used PWM through this pin to control a servo – originally using a servo with analog feedback to measure the analog position of the servo’s wiper and determine what PWM values can be used to move the wiper back and forth.

arduino, AZ3166, IOT, MXChip

Programming the AZ3166 MXChip Azure DevKit – reading analog values through physical pins

In this series of posts about the AZ3166 MXChip Azure Devkit, I’ve already written about:

This post is going to be about another fairly basic concept – reading analog values – but this is the first post in the series where I’ll connect external physical components to the device. In this post, I use a potentiometer to control the size of a potential difference, and use the AZ3166 MXChip device to read and display that difference.

WP_20171022_19_25_48_Pro

Setting up the device and potentiometer

The physical set up of this experiment is straightforward, as shown in the photo above – I just connected a potentiometer to the external edge connector, with 3v and 0v connectors to each end of the potentiometer, and using physical pin 5 to measure the potential difference as the rotating element moves between the ends.

My potentiometer was 2K, but that was just what I had closest to hand.

Writing the code

This code is very similar to the standard Arduino example to measure analog potential difference.

Physical pin 5 on the edge connector translates to Arduino virtual pin 4, so in my code the sensor pin is set to 4.

The analogRead function stores a representation of the potential difference in values from 0 to 1023, where 0 represents 0v and 1023 represents 3v.

I decided added a little bit of extra functionality to the sketch:

  • The red LED’s brightness blinks with a delay in milliseconds corresponding to the analog value read – at 3v, the analog value is 1024 so the LED is red for 1.024s, and then switched off for 1.024s.
  • I’ve also used the built in OLED display function to write the analog value on the device’s screen.

The code for the sketch is below:

#include <OledDisplay.h>
 
int sensorPin = 4;
int RED_LED = 20;
int inputValue = 0;
 
void setup() {
  Screen.init();
}
 
void loop() {
 
  // Write heading to OLED display
  Screen.print("Analog Value:", false);
 
  // Read potential difference through sensor pin
  inputValue = analogRead(sensorPin);
 
  // Write this value to the OLED screen
  char buf[10];
  sprintf(buf, "%d", inputValue);
  Screen.print(1, buf);
 
  // Now flash the red LED.
  // The analog input is between 0 and 1024
  // and therefore the delay will be between
  // 0ms and 1024ms
  digitalWrite(RED_LED, HIGH);
  delay(inputValue);
  digitalWrite(RED_LED, LOW);
  delay(inputValue);
}

And the photo below shows the analog value written to the OLED display.

reading_on_oled

Wrapping up

This was a very short post about reading analog values with the AZ3166, which is a well understood concept in the Arduino world. We can use the analogRead function with the AZ3166 in the same way as we use it in Arduino code, and can read analog signals through physical pin 5 (Arduino virtual pin 4). The example where we read the how a voltage is divided by a potentiometer isn’t hugely useful on its own, but it’s a useful concept to understand to the AZ3166 for other projects – we can read values many other external peripherals using the same principles.

arduino, AZ3166, MXChip

Programming the AZ3166 MXChip Azure DevKit – mapping virtual Arduino pins to physical digital I/O pins

Last time I wrote about getting started with the AZ3166 device – just a brief introduction to the on-board sensors and outputs, and I also wrote a simple application to demonstrate how to turn the red, green and blue LEDs on and off.

In that application, I mentioned that we can control the on/off status of the LEDs by writing a high or low value to three of the digital pins on the device. The numbers that I wrote digital values to were:

  • Red LED – Arduino pin 20
  • Green LED – Arduino pin 19
  • Blue LED – Arduino pin 39

WP_20171015_19_27_55_Pro

The photo above shows a Kitronik edge connector – but you can see that the number of pins only goes up to 16. So there was a mystery here – how is it that we switch the blue LED on in the Arduino code by accessing pin 39, when there aren’t actually 39 pins on the device?

Of course the answer is that the Arduino pin numbers don’t correspond to physical pins on the device – I prefer to think of them as virtual pins. I wasn’t able to find anyone else’s research on how to map physical pin numbers to Arduino virtual pin numbers, so I’ve mapped them out in the table below.

I’ve combined data from the official pin breakout notes on GitHub and some of my own research.

AZ3166 Edge Connector

So if I want to switch on the User LED, I need to change the status of physical pin 8 (i.e. pin 8 on the Kitronik connector). And if I want to access this pin through the Arduino IDE, I need to change the status of virtual pin 45 in the Arduino IDE.

int PIN_8 = 45;
 
void setup() {
  // initialize the pins as digital output.
  pinMode(PIN_8, OUTPUT);
 
}
 
void loop() {
  // turn user LED on
  digitalWrite(PIN_8, HIGH);
  delay(1000);

  // turn user LED off
  digitalWrite(PIN_8, LOW);
  delay(1000);
}

So with the table above, we can access the all the physical digital pins on the AZ3166 MXChip device with virtual pins numbers in Arduino code.

But what about analog I/O? Next time I’ll write about measuring external analog voltages using the AZ3166 device.


About me: I regularly post about Microsoft technologies – if you’re interested, please follow me on Twitter, or have a look at my previous posts here. Thanks!

arduino, AZ3166, IOT, MXChip

Programming the AZ3166 Azure DevKit – getting started

I’ve been looking forward to the release of the Azure AZ3166 “MXChip IoT DevKit” – a device with lots of sensors and outputs built into the device, that I can securely connect to IoT Hubs in the Azure cloud.

I’ve a few different posts planned about this device – in this post, I’ll write about the installation process, some small issues I found, and a basic application to interact with on-board LEDs by configuring pins as digital outputs.

WP_20171015_19_26_41_Pro

The device has the on-board features:

You can read more about the Azure AZ3166 here.

So because these are all on-board, that makes accessing them and using them really easy (particularly because all of the items above have great API documentation, and most have example code).

A couple of the features of this device I found very interesting were compatibility with Arduino code, and the connecting finger which has the same form factor as the BBC micro:bit – I’d like to find out how I can use this device to work with some of the breakout boards I use with my Arduino.

Software installation and getting started

There’s already a really good description of how to get started with this kit – check it out here. There’s no point in me repeating all of that here, so in summary:

mxchip_install

Things that didn’t go as well

This almost perfectly worked out of the box for me – but I like to share the small issues I experienced because I hope they’ll be roadsigns that help other developers avoid wasting time on the same problems.

  • The DevKit only works on 2.4GHz Wi-Fi. This is in the FAQ, but I didn’t read this right off the bat, and spent some time wondering why my hardware couldn’t find my Wi-Fi. Turned out that it was because I was running both 2.4GHz and 5GHz signals out of my router – when I changed the router settings to only broadcast on 2.4GHz, my device found the Wi-Fi straight away.
  • There are lots of warnings when you try to compile any application for the device through the Arduino or VSCode environments. The Arduino compiler output, even for ‘Hello World’ type applications, was absolutely littered with warnings. I’ve pasted a few below.
#warning toolchain.h has been replaced by mbed_toolchain.h, please update to mbed_toolchain.h [since mbed-os-5.3]
...
#warning wait_api.h has been replaced by mbed_wait_api.h, please update to mbed_wait_api.h [since mbed-os-5.3]
...
#warning sleep.h has been replaced by mbed_sleep.h, please update to mbed_sleep.h [since mbed-os-5.3]
...
#warning rtc_time.h has been replaced by mbed_rtc_time.h, please update to mbed_rtc_time.h [since mbed-os-5.3]

I spent some time uninstalling and re-installing different programs, and I even to the extent of installing the software on a fresh instance of Windows 10 in case another application or library conflict was causing this – it made no difference. But ultimately, these warnings didn’t impact any applications that I deployed.

arduino_output

  • Problems displaying serial output in the Arduino IDE Serial Monitor. I’m used to deploying applications to the Arduino using the Arduino IDE, specifically targeting a COM port at deployment time. I created an application for the AZ3166 with a few “Serial.println” statements, hoping to use the Serial Monitor built into the Arduino IDE to read the output. But after deploying to the AZ3166 DevKit device, I tried to open the Serial Monitor, and got an error message saying the IDE couldn’t find the COM1 port. The solution was to manually set the COM port through the “Tools -> Port” sub-menu, and the default port selected by the IDE isn’t actually the port that serial output is sent through.

A simple blinky application for the DevKit

There is already an example for the on-board RGB LED, but I wanted to work at a lower level to access on-board LEDs, rather than using existing libraries. I just needed to find out what Arduino pin numbers corresponded to the LEDs on the DevKit device.

I found that the numbers corresponding to the three basic LED colors are:

  • Red LED – Arduino pin 20
  • Green LED – Arduino pin 19
  • Blue LED – Arduino pin 39

I’ll post more about DevKit to Arduino pin mappings in a later post.

With this knowledge, it was very simple to create a variation on the standard “blinky” application, where I turn the red LED on and off, then the green LED, and finally the blue LED.

I’ve pasted the code below – just like regular Arduino C code.

int RED_LED = 20;
int GREEN_LED = 19;
int BLUE_LED = 39;
 
void setup() {
  // initialize the pins as digital output.
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(BLUE_LED, OUTPUT);
}
 
void loop() {
  // turn red LED on
  digitalWrite(RED_LED, HIGH);
  delay(1000);
 
  // turn red LED off
  digitalWrite(RED_LED, LOW);
  delay(1000);
 
  // turn green LED on
  digitalWrite(GREEN_LED, HIGH);
  delay(1000);
 
  // turn green LED off
  digitalWrite(GREEN_LED, LOW);
  delay(1000);
 
  // turn blue LED on
  digitalWrite(BLUE_LED, HIGH);
  delay(1000);
 
  // turn blue LED off
  digitalWrite(BLUE_LED, LOW);
  delay(1000);
}

So much for modifying the status of an LED on-board – now how about using code to adjust the digital statuses of pins on the connecting finger?

WP_20171015_19_27_55_Pro

First we have to be able to physically attach to the connecting finger, which I was able to do using a connector breakout. But I didn’t know what the numbers on the connector board corresponded to…next time I’ll write about using the connector.


About me: I regularly post about Microsoft technologies – if you’re interested, please follow me on Twitter, or have a look at my previous posts here. Thanks!