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.

One thought on “Using the MXChip AZ3166 Azure DevKit with Arduino – pulse-width modulation and servos

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s