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

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 Aliases

As well as naming all the LED pins, this matrix makes it clear that there are:

  • 2 analog pins,
  • 11 digital pins,
  • I2C pins,
  • SPI pins,
  • 2 button pins, and
  • 1 PWM pin.

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.

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!

arduino

Two ways to initialize an array in C

I don’t often post about C, but I’ve been programming a lot in the Arduino world recently, and thought I’d post a quick couple of tips on a small programming challenge I encountered.

I needed to declare a character array (of length 64) – this is pretty simple.

char radioTextData[64];

And when I write the contents of this array to the Serial output…

for (short i = 0; i < sizeof(radioTextData); i++) {
    Serial.print(radioTextData[i]);
 }

…instead of seeing blank values, I see character values which were previously in the memory location used by my array variable.

So how can I make this array initially empty?

The hard way – write a function to loop over the array

As a .NET developer, this seemed like it should be pretty easy to me – in .NET variables are passed by reference so I can just pass the array into a method, and iterate over the array to set each value to whatever I want it to be (or use clever framework methods).

But when programming in C for the Arduino, it’s a little more complex to clear an array using a loop in a separate function. First we have to set up a pointer to the original array.

char radioTextData[64];
char* pointerToRadioTextData = radioTextData;

And now we have a pointer to the array, we can pass that to a function to process it – we also need to pass the size of the array because we can’t work that out from the pointer to the original array.

void clearArray(char* myArray, short sizeOfMyArray) {
    for (short i = 0; i < sizeOfMyArray; i++)
    {
        myArray[i] = ' ';
    }
}

The easy way – use memset

memset allows us to initialise an array to a specified character – so using just one line of code I can achieve the same result as in the first part of this post by passing the array, the size of the array, and the character that each element of the array to be initialised to.

memset(radioTextData, ' ', sizeof(radioTextData));

Summing up

So obviously to initialize and array, my code will use the easy way – it’s short, clear and elegant. But the technique of processing an array in C by passing a pointer to the start of the array is useful too.