Over the last few days I’ve been gradually re-coding my Gadgeteer game from C# to VB.net now that the .Net Micro Framework 4.2 implementation is ready for the Spider.
That job is now finally over and the game now running as it was under the 4.1 framework.
So with a breadboard the new soldered Extender module and some connector wires and pull up resistors; it was all connected together and powered on. No magic blue smoke meant that things may actually be working ;-).
Fez Spider with SP03
The device uses either serial or I2C communication to communicate which is supported by the FEZ Spider. It took a lot of looking around and a couple of questions on the Tiny CLR forum but I managed to make a class that allowed the communication between the two and managed to make it speak for the first time. Below is that class:
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
namespace FEZ_Speak
{
class SP03
{
// initialse the device object
private I2CDevice _sp03;
// setup constants
private const byte SP03ADDRESS = 0x62;
private const int SP03CLOCKRATE = 100;
// setup default speaking paramaters
private byte _volume = 0x00;
private byte _speed = 0x03;
private byte _pitch = 0x05;
// Initialise the hardware
public SP03()
{
I2CDevice.Configuration config = new I2CDevice.Configuration(SP03ADDRESS, SP03CLOCKRATE);
_sp03 = new I2CDevice(config);
}
// Speech properties
public byte Volume
{
get { return _volume; }
set { _volume = value; }
}
public byte Speed
{
get { return _speed; }
set { _speed = value; }
}
public byte Pitch
{
get { return _pitch; }
set { _pitch = value; }
}
// Methods
// Say something
public void Say(string speech)
{
WaitForSpeechFinish();
I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[3];
xActions[0] = I2CDevice.CreateWriteTransaction(GetSettings());
xActions[1] = I2CDevice.CreateWriteTransaction(ConvertText(speech));
xActions[2] = I2CDevice.CreateWriteTransaction(SayIt());
if (_sp03.Execute(xActions, 1000) == 0)
{
Debug.Print("Failed to perform I2C transaction");
}
}
private byte[] ConvertText(string text)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] buffer = encoding.GetBytes(text);
byte[] result = new byte[buffer.Length + 2];
result[0] = 0;
result[1] = 0;
buffer.CopyTo(result, 2);
return result;
}
private byte[] GetSettings()
{
byte[] speechConfig = new byte[] { 0, 0, _volume, _pitch, _speed };
return speechConfig;
}
private byte[] SayIt()
{
return new byte[] { 0, 0x40 };
}
private void WaitForSpeechFinish()
{
bool speaking = true;
byte[] request = new byte[1] { 0 };
while (speaking)
{
byte[] response = new byte[1];
I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];
xActions[0] = I2CDevice.CreateWriteTransaction(request);
xActions[1] = I2CDevice.CreateReadTransaction(response);
if (response[0] == 0)
speaking = false;
}
}
}
}
And here is the code that consumed that class:
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
namespace FEZ_Speak
{
public partial class Program
{
// This method is run when the mainboard is powered up or reset.
void ProgramStarted()
{
SP03 speechUnit = new SP03();
speechUnit.Say("Hello Tiny C L R.");
}
}
}
After running this a growly computer voice spoke the words. In case anyone doesn’t believe me, here is the evidence 😉
As I’m using the Gadgeteer/.Net Micro Framework, I’ve been forced to learn some more c# ;-).
I came across an issue where Multi-Dimensional arrays are not compatible with the micro framework.
Thanks to the help of Architect from the TinyCLR.com forums (See his blog link “Break Continue” in the blogroll to the right of the post), I’ve now been introduced to jagged arrays in C# which solved the issue.
This failed:
private char[,] maze = new char[20,20];
So I now use the following code to achieve the same thing:
private char[][] maze = new char[20][];
// Stuff
private void InitialiseMaze()
{
for (int lp = 0; lp <= 19; lp++)
{
maze[lp] = new char[20];
}
}
To see it in use, Here is a section of code used to populate the array from the code:
// Stuff
private void LoadMaze()
{
// read in the text file and convert to a string.
string path = _mazePath + @"\store\" + _currentLevel + ".map";
byte[] rawBytes = _storageDev.ReadFile(path);
char[] rawCharacters = System.Text.UTF8Encoding.UTF8.GetChars(rawBytes);
string tmpMap = new string(rawCharacters);
// Now split the text file into lines using the \r character from the text file
// note this will leave the \n character at the end of each line
string[] lines = tmpMap.Split('\r');
// Get the header, removing the \n
string header = lines[0].Trim('\n');
// check maze version and the dimensions of the maze
string[] bits = header.Split('|');
string ver = bits[0];
int width = int.Parse(bits[1]);
int height = int.Parse(bits[2]);
if (ver != "1.0")
{
throw new Exception("Maze version is incorrect");
}
for (int y = 1; y <= height; y++)
{
char[] row = lines[y].Trim('\n').ToCharArray();
for (int x = 0; x < width; x++)
{
maze[x][y-1] = row[x];
}
}
}
It’s been a while since I’ve posted anything. Basically I’ve been busy with other things recently but I intend to get back into more coding with Azure and Windows Phone etc. soon.
On another note I’ve just purchased one of the .Net Gadgeteer FEZ Spider kits.
Unfortunately, the current SDK (4.1) does not support VB coding, but I hear that when 4.2 is released it will.
If you are wondering what .Net Gadgeteer is click the link.
It uses the .Net Micro Framework and is extremely easy to code for in Visual Studio. (You can use C# Express too)
I’ll be posting more once the kit has arrived and I have had chance to play with it. I was lucky to get on as it’s sold out due to popular demand in a lot of places.