Skip navigation
2015

Yes I am an udergraduate Engineering student and have been busy with my pre-final year exams, which were keeping me barred to progress in this design challenge. I waited a long to tinker with my new kits and finally I can start now. I have planned on journey ahead in Enchanted Wardrobe and will document the whole build in number of blog post.

 

1) Taking Yun to the cloud and talk to Yahoo Weather API using Temboo.

2) Parseing the XML response from Yahoo to extract the useful required information.

3) Mapping the temperature and current weather conditions to type of clothes suggested to wear on that specific day.

4) Adding a Reed/Door open switch to make Yun starts fetching data and process it only when wardrobe door is opened to make it less power hungry.

5) Adding text-to-speech capabilities and RGB i2c LCD to display and speaks out current weather conditions.

6) Adding a user button on application of which the suggested clothes section will automatically come ahead for easy access.(Need to figure out the mechanics behind and tinker with my wardrobe).

7) Optional: Mapping temperature data to RGB values using linear interpolation and show it on RGB LED wrapped in circle inside wardrobe and programmed using RGB infineon shield.

 

Lets start the journey, though am starting a bit late, but wish to complete it on time. Fingers Crossed . Only 4 weeks left..

I want to control windows using arduino.I got Tinkerkit servo in competition kit.But I just found another good solution,I found a 10 RPM 12 V DC geared which has pretty nice torque.So,need to make

decision between this two.What are your suggestions?

 

IMG_20150531_182142.jpg 

coolbox

Working with yun

Posted by coolbox May 31, 2015

Hello friends

 

I was trying to getting started with arduino yun.I was able go get it on my laptop's wi-fi.Then I tried to re-configure it using 192.168.240.1 because arduino.local was not working.After re-configuring it showed that arduino is being restarted.But I cannot find it in my wi-fi panel after restart is it normally happen or arduino will connect my assigned network.

 

Regards,

parth

Not that I can play an mp3 file, let's find a way to build a simple TTS speech

As we live in a connected world, why not leveraging the power out there on the web to overtake hardware limitations?

 

I found an interesting site here

http://tts-api.com/

 

that provides a text-to-speech web service

 

To convert a text programmatically from NodeJS, the URL to invoke is the following one

 

var mp3url='http://tts-api.com/tts.mp3?q='+encodeURIComponent(text);

 

Given this url, we can use NodeJS's http.get to download the mp3 file. Here is the code

 

function getMp3(mp3url, filename, cb)
{
console.log("Getting url " + mp3url);
http.get(mp3url, function(response) {
   if (response.statusCode > 300 && response.statusCode < 400 && response.headers.location) {
     console.log("Redirect detected");
     // The location for some (most) redirects will only contain the path,  not the hostname;
     // detect this and add the host to the path.
     if (url.parse(response.headers.location).hostname) {
       // Hostname included; make request to response.headers.location
       console.log("Redirecting to " +  response.headers.location);
       getMp3(response.headers.location,filename, cb);
     } else {
       // Hostname not included; get host from requested URL (url.parse()) and prepend to location.
     }
   // Otherwise no redirect; capture the response as normal           
   } else {
     response.setEncoding('binary');
     response.on('data', function (chunk) {
       console.log("Data " + chunk.length);
       _data =_data.concat(chunk);
     });
     
     //the whole response has been recieved, so we just print it out here
     response.on('end', function () {
        console.log("End " + _data.length);
       
        var f = fs.createWriteStream(filename);
        f.write(new Buffer(_data, 'binary'));
        f.end();
       
        cb();
     });
   }
});
};

 

Here are two kind of magic:

  1. Redirection: when the above-mentioned URL is requested, the request is redirected to a URL like this one

http://media.tts-api.com/1e4e888ac66f8dd41e00c5a7ac36a32a9950d271.mp3

NodeJS's http.get does not provided redirection-following capabilities, we have to implement the logic using the following lines of code

if (response.statusCode > 300 && response.statusCode < 400 && response.headers.location) {
console.log("Redirect detected");
// The location for some (most) redirects will only contain the path,  not the hostname;
// detect this and add the host to the path.
if (url.parse(response.headers.location).hostname) {
            // Hostname included; make request to response.headers.location
            console.log("Redirecting to " +  response.headers.location);
            getMp3(response.headers.location, cb);
} else {
            // Hostname not included; get host from requested URL (url.parse()) and prepend to location.
        }

 

  1. by default, NodeJS filesystem assumes data received after a GET is a text. In this case, we are receiving binary data, so we have to let NodeJS know we want it to treat data as an octect stream. This is accomplished by means of the following instruction

 

response.setEncoding('binary');

 

Finally, we have to instruct NodeJS to parse for a specific string from on serial port

 

yunPort = new serialPort.SerialPort('/dev/ttyATH0', { baudrate: 115200 });

yunPort.on('data', function(data) {

  console.log('data ' + data);
  if (_ws)  
  {
     _data = _data + data;
    if (_data.indexOf("\r\n") > 0)
    {
      // check if this is a PLAY command
      if (_data.substring(0, 5) == "PLAY")
      {
        var text = _data.substring(6);
        var mp3url='http://tts-api.com/tts.mp3?q='+encodeURIComponent(text);
        var filename = '/mnt/sda1/' + text.replace(' ', '_') + '.mp3';
        getMp3(text, filename, function() {
             var exec = require('child_process').exec;
             exec('/usr/bin/madplay ' + filename);
         });
      }  
      else 
        _ws.send(_data);

      _data = "";
    }
 }
});

 

Now, on the Atmel side I can simply write

 

Serial.println("hello world");

 

to make MagicHat speak! That's Internet power!

After finishing the data acquisition part of the project, let's see how to make the MagicHat a little more... magic

 

To make Arduino Yun speak, I first need an external USB audio card like this one here

 

IMG_20150528_171510.jpg

 

Then, I need to install an mp3 player that will play a file stored on SD card. Installing the mp3 player is just a few packages away...

 

opkg update
 opkg install kmod-sound-core 
 opkg install kmod-usb-audio 
 opkg install madplay


 

Since the control logic runs on the Atmel side of Arduino Yun, we need to devise a way to launch the player. To send data from Atmel to Linino I disabled the bridge, so now Serial1 is read by NodeJS.

So, the firmware running on Atmel will send out (by calling Serial1.println) a string like

 

PLAY helloworld.mp3


 

and NodeJS will launch the mp3 player to play to "helloworld.mp3" file

 

This can easily achieved using the NodeJS's 'exec'  package

 

var exec = require('child_process').exec;
exec('/usr/bin/madplay ' + filename);


Hans also found the "pretty-wifi-info.lua" script for checking the Yún's WiFi status, it nicely abstracted Hans code from the hardware so he wrote a wrapper for that rather than writing his own. He used the "parse" module to interpret the output. That installed nicely on the Yún for a change.

 

pip install parse


 

To avoid key errors he defaulted all of the common values to be "unknown".

# Get the Wifi Status into a dictionary
import subprocess
from parse import *

def parselines(s):
    lines = s.splitlines()
    d = {}
    for line in lines:
        p = parse("{}: {}",line)
        if p:
            d[p[0]] = p[1]
    return d

def getWifiStatus():
    w = subprocess.check_output("/usr/bin/pretty-wifi-info.lua")
    p = parselines(w)
    for key in ('Mode','Interface name','SSID','Signal','Encryption method','Active for','IP address','MAC address','RX/TX'):
        p.setdefault(key,'Unknown')
    return p

p = getWifiStatus()

print p['Mode']
print p['Interface name']
print p['SSID']
print p['Signal']
print p['Encryption method']
print p['Active for']
print p['IP address']
print p['MAC address']
print p['RX/TX']

 

Reference

 

https://docs.python.org/2/library/subprocess.html#using-the-subprocess-module

https://pypi.python.org/pypi/parse

https://wiki.python.org/moin/KeyError

Image (3).jpg

 

No electronics in today's post. Just a few pictures of the work on the sub-chassis.

I'm avoiding to drill holes in the nice turntable coffer. I'm crafting a light carton base that nicely fits inside the turntable.

The material I use is from my son's school project. He's building an architectural model of a house.

 

Photo 27-05-15 21 51 21.jpg

 

Building the sub-chassis

 

It's just the fancy name for a piece of carton. As prototype I used part of a pizza box.

 

Photo 27-05-15 10 59 14.jpg

 

I made that fit using the trial and error method.

Photo 27-05-15 10 59 36.jpg

 

Then I used it as template for the cardboard.

 

Photo 27-05-15 11 00 15.jpg

 

Photo 27-05-15 11 15 14.jpg

 

This is the end result: a nicely fitting mounting plate.

After cutting it out, I re-traced the sides with an extra line of red sharpie to give it that professional finished look .

 

Photo 27-05-15 11 26 04.jpg

 

Having this removable base plate will make it easier to work on the different parts.

And I can take everything out at once when I have to revert the turntable to its original state.

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story
crjeder

Planing the Final Spurt

Posted by crjeder May 27, 2015

Inspired by jancumps post 1958 Turntable from the Black Forest - 21: Right-Sizing my Plans I decided to plan the last 5 weeks of the challenge and look back on what I've achieved.

 

Looking Back

 

The features I've promised are:

  1. No user interaction necessary besides hanging the keys
  2. Make key status available on-line
  3. RGB-LEDs to display status of the absent persons
  4. RESTful / IFTTT  / Tasker (android) interface

Additional, optional features I have proposed:

  1. Record speech messages which get played when the person / respectively the key returns
  2. Detect a specific key ring independent of the hook it was hanged on
  3. Placing "ToDo" lists (on paper) on the board and sending "accepted" messages to listeners

 

I had no plan how to reach the the goals I've set for the challenge until now. Not that I did not know the value of a good project plan, but I am not as experienced as the other contenders therefore I could not estimate the time I would need. Even the proposal was just a wild guess of what could be possible within 15 weeks.

Currently I am able to detect key rings independently of the hook they where placed on and send out the status to a prototype client which is integrated into tasker. Therefore I've achieved 1, 2,4 and b). This is not to bad. I am currently working on 3 and I am evaluating 2 options:

  • using the Infineon RGB Shield (Product LinkProduct Link) and multiplexing the output to 5 RGB LEDs
  • using WS2812B LEDs

In both cases I have the challenge of receiving an interrupt at the end of a PWM period. I've read the Data sheets of both the Infineon and the AMD processor. In both cases they mention that it should work but I can not find out how. I've already spent the combined spare time of 2 weeks on this problem. The documentation for the SAMA5D4 simply is not made for the hobbyist so I might overlook something obvious for the expert.

 

Looking Forward

 

Now it's time to do a top-down project plan. There are 5 weeks left and one important goal to reach along with the necessary project documentation. I guess I need 2 weeks to do the cleanup and do the final presentation for the challenge. That leaves me with 3 weeks to solve the Problem, implement the server on the SAMA5D4 (Product LinkProduct Link). For the later 1 estimate 1 week since it is already partially solved. This leaves me with 2 weeks of experimenting and debugging the code for driving 5 to 8 LEDs. Sounds doable but hopefully I'll find the missing puzzle peace soon.

Image (6).jpg

This is my first SAMA5D4 firmware that takes a reasonable sample of audio range signals.

I'm using the ADC buffer mechanism. The converter fills the buffer in the background.

I'm reading the values and log them. Later I'll use them to drive the light organ of the enchanted table.

 

Photo 25-05-15 21 18 40.jpg

 

 

What's Happening in the Firmware?

 

I'm doing exactly the same as what's documented on IioAdcDriver < Linux4SAM < TWiki.

But in C++. You can find the instructions back in the code.

For clarity, I'm using the same comments as on the AT91 pages.

 

Set up the channels in use

linux

echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en



c++

      ofstream osChannel("/sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en", ios::out);
      if (osChannel.is_open()) {
        osChannel << "1";
        osChannel.close();
      } else {
        cout << "Unable to open file " << "/sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en" << "\n";
      }



Set up the trigger we want to us

linux

echo "fc034000.adc-dev0-continuous" > /sys/bus/iio/devices/iio:device0/trigger/current_trigger



c++

      ofstream osTrigger("/sys/bus/iio/devices/iio:device0/trigger/current_trigger", ios::out);
      if (osTrigger.is_open()) {
        osTrigger << "fc034000.adc-dev0-continuous";
        osTrigger.close();
      } else {
        cout << "Unable to open file " << "/sys/bus/iio/devices/iio:device0/trigger/current_trigger" << "\n";
      }


 

Set up the buffer length

linux

echo 100 > /sys/bus/iio/devices/iio:device0/buffer/length



c++

      ofstream osLength("/sys/bus/iio/devices/iio:device0/buffer/length", ios::out);
      if (osLength.is_open()) {
        osLength << MUESTRAS;
        osLength.close();
      } else {
        cout << "Unable to open file " << "/sys/bus/iio/devices/iio:device0/buffer/length" << "\n";
      }



Enable the capture

linux

echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable



c++
      ofstream osEnable("/sys/bus/iio/devices/iio:device0/buffer/enable", ios::out);
      if (osEnable.is_open()) {
        osEnable << "1";
        osEnable.close();
      } else {
        cout << "Unable to open file " << "/sys/bus/iio/devices/iio:device0/buffer/enable" << "\n";
      }



 

 

After that point, the ADC starts filling the buffer - available as character device  /dev/iio:device0.

I then go on and read these 128 samples of the buffer. After that, my code will go to do the light organ work - a topic for the next post.

 

There's still some dodgy code in my program. My algorithm to read from that character device isn't good.

I do know how to do it properly (I have the c example code from generic_buffer.c available).

I was just hoping that I could simplify that code using a c++ character stream. I just don't seem to be able to use the stream mechanism reliable with a volatile character device yet.

I sometimes receive the two bytes that form my value in reverse order. I know that's me, because the sample code does it just fine. So there's still work to do.

 

 

  while(1) {
    ifstream myfile(fileName, ios_base::binary);
    if (myfile.is_open()) {




      for( i=0; i < MUESTRAS; i++) {




        myfile >> uSampleA;
        myfile >> uSampleB;


        /**
         * Obviously, I don't know what I'm doing here.
         * I need to study generic_buffer.c to really understand
         * how to interpret /dev/iio:device0
         * I have a 10 bits result, most likely stored in 2 bytes
         * But the way I'm reading it back seems to give a random
         * order of the high and low bytes
         *
         * I'd better start learning the way to properly read the buffer
         * but for my light organ, the errors are in the noise range
         */


        uShiftedSample = uSampleA << 8;
        uShiftedSample |= uSampleB;


        if (uShiftedSample > 1023U) {
          uShiftedSample = uSampleB << 8;
          uShiftedSample |= uSampleA;
        }


        //cout << uSampleA << " " << uSampleB << " " << uShiftedSample << "\n";


//        data[i] = uShiftedSample/4-128; //Convertimos de 0..1024 a -128..127
        data[i] = uShiftedSample; //Convertimos de 0..1024 a -128..127
        im[i] = 0;                    // parte imaginaria = 0


      }


      cout << "\nsamples :\n";
      for( i=0; i < MUESTRAS; i++) {
        cout << (int)data[i] << ",";
      }
      cout << "\n";




    } else {
      cout << "Unable to open file " << fileName << "\n";
    }


    // taken out of sample loop
    myfile.close();
  }



 

For my light organ however, this sample quality will do.

In the next installment I'll transpose the samples to the -128..127 range.

Then to go through the FFT library, and I'll chop them up in bass, middle and treble...

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

Good morning Ricksville

 

One morning Farmer Hogg woke up, looked out the window and checked the colour of his field.He headed down to the kitchen and turned on his internet radio, Rick Astley was playing so he turned it off again.

Old Mother Hubbard turned on her computer to check her inventory management system. A Rick Astley video was playing, she liked Rick so left it playing and forgot what she was about to do.
At the top of the stairs, around the back of the town hall, the man from the Historical society was trying to find film footage of the old mine workings but every time he clicked on a link, Rick Astley appeared.
The inn keeper had Rick Astley playing on his jukebox and also on the POS system.

The woodcutter was normally a man of few words but after 30 minutes trying to rid his computer of Rick, he had managed to find a few extra ones that even the dwarves would have been shocked by.

The mayor turned on his TV to watch Lizzy the Lizard exercise video and also got Rick Astley. Enough was enough, a town meeting was called.


Mean whilst in the forest, Hans and Matilda were trying to connect up to the internet. "Strange?" said Hans, "the requests get past our firewall but timeout when reaching the town ISP, it is there because I can get a response by extending the timeout, but it just seems to be too busy to forward on our weather requests."

 

The old fashioned way


"We are going to have to do it the old fashioned way", said Hans. "Not the cat gut?!" cried Matilda. "Not quite that far back" he said. Hans rummaged in his spares box and brought out a tiny device that looked a bit like a cheese grater. "We can get the local temperature and humidity with this DHT22 and estimate the chance of precipitation from that" said Hans.

 

DHT22_bb.png   DHT22

 

// Based on the work of ladyada, public domain
#include "DHT.h"
#define DHTPIN 4     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
//DHT dht(DHTPIN, DHTTYPE, 30);
void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
}
void loop() {
  // Wait a few seconds between measurements.
  delay(2000);
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  Serial.print("Humidity: "); 
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *C ");
  Serial.println("");
}




 

Hans decided to pass the local temperature and humidity over to the Python script and if there is no network or an error it can still return a position reference for them. That way all the weather related algorithms are in one place. Hans could not find any algorithms that connected humidity to precipitation but he thought if he based it around the dew point that would give a very similar result to the old cat gut.

 

The boy who cried wolf

 

Mean while at the town meeting a small boy pointed to a logo in the corner of a screen playing Rick Astley videos and cried "wolf! wolf!", the townsfolk told him to be quiet and stop bothering them.

 

Next: Enchanted Objects Design Challenge - This is not the WiFi you are looking for

 

Reference

 

Adafruit Learning - Using a DHTxx sensor

Estimating air humidity from temperature and precipitation measures for modelling applications

How do I calculate dew point?

Precipitation Estimation in Canada using Archival Climate Data - William A. van Wijngaarden* - Physics Dept., York University, Toronto, Ontario

Lecture: Humidity as an Element of Weather, Dr. Rodrigue

So this weekend the genie buckled down, determined to finish the project he had started. His heart was delighted to see that he had finally finished all the wiring to his house! Now all that need to be done was furnishing and some aesthetics!


#include <TimeAlarms.h>
#include <infineonrgb.h>
#include <Wire.h>
#include <Time.h>
#include <stdlib.h>

InfineonRGB LEDS;

void setup() {
     // put your setup code here, to run once:
     LEDS.begin();   
     LEDS.SetDimmingLevel(0x0000);
     setTime(5,41,0,5,24,14); // set time to Saturday 5:41:00am May 24 2015
     Alarm.alarmRepeat(5,41,05, Light);  // 5:41:05am every day

}

void loop() {
     // put your main code here, to run repeatedly:
     Alarm.delay(1000);
}

void Light() {
     LEDS.SetIntensityRGB(0x01FF, 0x0000, 0x0000);
     LEDS.SetDimmingLevel(0x01FF);
     delay(3000);
     LEDS.SetDimmingLevel(0x03FF);
     delay(3000);
     LEDS.SetDimmingLevel(0x07FF);
     delay(3000);
     LEDS.SetDimmingLevel(0x0FFF);
     delay(3000);
     LEDS.SetDimmingLevel(0x07FF);
     delay(3000);
     LEDS.SetDimmingLevel(0x03FF);
     delay(3000);
     LEDS.SetDimmingLevel(0x01FF);
     delay(3000);
     LEDS.SetDimmingLevel(0x0000);
}

 

Above is the code that I used for the video, this will be implemented in the final code, but not using the TimeAlarm library. Also I would like to give Inderpreet Singh a huge thanks. His library infineonrgb.h was very useful. You can find it here.

 

                                                                                                    

 

Stay tuned to see what magic the genie preforms next!

I'm now at the point in the project where I can match what I have with what I can.

 

Photo 22-05-15 23 36 57.jpg

 

I overestimated my skills when I announced that I would try to integrate a Shazam-like service into my player.

Or more honest: I didn't overestimate. I set this a s a goal to force myself to reach as far as I could.

At that time, I expected that I'd be faster to adapt embedded  Linux.

Based on no particular evidence, I predicted for @self that I'd be on track with that technology fast.

 

And I didn't get on track fast. It was a steep curve. And that steep curve resulted into unexpected results.

My flashy goals are out of reach. No way will I be able to get that song recognition part integrated.

It's a magnitude more complex than what I learned up till today. I'm  a realist. That's not something I'm going to achieve right now.

 

But I think that this is offset by something more valuable for the outside world. I've shared my struggle.

I will not deliver that mystical enchanted song recognition system.

But on the way of not delivering that, I have written a trail of experiences and HOW-TO's that may help the community.

I learned a lot. And I hope that this opens up opportunities for you.

Along the way, this may have caused some discomfort left or right. It will turn out alright in the end.

 

Achievable Goals

 

First, there are all the things that I've shown before (turntable motor drive, speed detection, control loop, audio sampling, FFT and spectrum analysis, servo lift).

As a stretch for myself, I'm going to port as much as I can of that into the SAMADA5D4.  As a learning opportunity for @self,

And as a tribute to the power of that processor.

 

To make it connected, I plan to beam a part of the audio information to the cloud.

I'll broadcast a message with the bass, mid and treble info of the record currently playing.

Subscribers all over the world (most likely me only ) can subscribe and animate something based on that.

My animated thing will be an internet connected light organ, powered by Yún and Infineon LED shield. Yours may be a frequency analyzer visualization thingy..

Latency  be damned .

 

Ah, and I don't have high power leds for the light organ. Send me some please.

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

The week was full of rain and clouds for the poor genie all week. Unable to leave his house and make any progress on the things that needed to get done, due to the unfortunate consequences of doing your electrical work in the rain, but today the sun peeked out from behind the clouds and shone with the brightness of 2000-2500 lumen. It was magnificent! However, shortly after its arrival, the clouds took over again . But while the sun was out the genie made headway on his electrical wiring of his sweet new crib. He set the power supply to roughly thirty volts and tested out his lights to see if they worked.

                                                                      

And it worked! How excited the genie was! This was a huge step in the right direction with the build of his new pad. Now all that was needed to be done was wire it all up to his sweet new dimmer and you could call him Xzibit Jr.

                                                                                                     

WAIT! There is no light!!!! What in the world is going on? No explosions, check. No fire or smoke, check. Then what? The genie checked the voltage coming out and the light intensity and found:

                                                                 

But that doesn’t make sense! 30 Volts in and only a 100th of that out? How could this be? The genie has yet to figure this out, but he will be working diligently over the weekend to figure out a solution!

                                                                                   

I don't know if it was already there for a longer time, or that I missed it before,

Yesterday and today I found significant new and interesting content for our SAMA5D4 board.

 

 

The content is available from the Linux4SAM home page, and from the side menu. There's a step-by-step explanation on loading a bootloader and binary to the board, including screen captures.

And there's a new release of the Linux demos, 4.7. I've installed that yesterday and the Linux distro works flawlessly. I'm using the board headless, so I haven't run any of the graphical demos.

 

The image loaded very smoothly.

I just had to adapt demo_linux_nandflash.bat to match the COM port that's assigned on my PC (I first started SAM-BA in GUI mode to check the COM name it's expecting..

 

sam-ba.exe \USBserial\COM6 at91sama5 .....




 

The board started up perfectly. Impressed.

 

Now for me it's back to finding out if the distro contains the ADC driver, and what it's name is.

I'm trying the Buffer and Hardware Trigger  capabilities of the SAMA5D4.

I follow the instructions of http://www.at91.com/linux4sam/bin/view/Linux4SAM/IioAdcDriver.

 

In Part 1, I enabled the hardware trigger from the linux prompt.

In this post, I'm testing the buffer with the test tool generic_buffer.

 

Building the Test Tool

 

generic_buffer is available as c source. There's a number of them available in different versions on the internet, but not all compile for this board (or for my tool chain).

I steered away from examples that use the be16toh function. I got errors when I compiled those.

There are also versions without that function.

I used (without further analysis, just because it was the first hit) kernel-rsbac-source-3.0.2-1mdv-1-1-mdv2011.0.i586.rpm.59587983/usr/src/3.0.2-rsbac-1mdv/drivers/staging/iio/Documentatio…

Use the one from the atmel git: https://raw.githubusercontent.com/linux4sam/linux-at91/master/drivers/staging/iio/Documentation/generic_buffer.c

 

Run the Test Tool

 

My first run is with the analog input connected to ground. I'm doing the exercise while writing the blog, so what you see here is exactly as it happens.

 

Photo 21-05-15 21 19 47.jpg

 

As a first step, I load my compiled program

 

rz -e -b -X generic_buffer
chmod +x generic_buffer
















 

and execute the steps documented in part 1:

 

modprobe at91_adc
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en
echo "fc034000.adc-dev0-continuous" > /sys/bus/iio/devices/iio:device0/trigger/current_trigger
echo 100 > /sys/bus/iio/devices/iio:device0/buffer/length
echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable















 

And now the moment suprême: running that binary:

 

# Don't use at91_adc when working with a 'device tree' linux distro ./generic_buffer -n at91_adc -t fc034000.adc-dev0-continuous -l 2














 

./generic_buffer -n fc034000.adc -t fc034000.adc-dev0-continuous -l 2

 

where:

  • at91_adc is the IIO driver
  • fc034000.adc is the IIO driver
  • fc034000.adc-dev0-continuous is the trigger name
  • 2 is the buffer lenght (I would expect 100 here because I echo 100 to buffer/length a few lines higher. I'm following the advice of linux4sam here.

 

And here I fail. Failed to find the at91_adc

My error message is related to the driver. I'm posting a new post on the at91.com forum to see what's wrong.

 

hold on...

 

 

While my post is open on the at91 forum, I'm continuing with investigations.

 

Here's where the code fails:

    /* Find the device requested */
    dev_num = find_type_by_name(device_name, "device");
    if (dev_num < 0) {
        printf("Failed to find the %s\n", device_name);
        ret = -ENODEV;
        goto error_ret;
    }
    printf("iio device number being used is %d\n", dev_num);













 

I'm going to check how find_type_by_name() works, and check in the ii0 folders if I find something obvious...

update May 22:

 

Solved. The error was caused by 2 things:

 

(see element14 question SAMA5D4 ADC driver - do you know a Linux image that has the driver?)

 

1. the source for generic_buffer.c : 

There's a multitude of versions of that file on the internet.
Here's the correct one: https://raw.githubusercontent.com/linux4sam/linux-at91/master/drivers/staging/iio/Documentation/generic_buffer.c

 

In the correct one, here's how the device is found:

 

 

dev_num = find_type_by_name(device_name, "iio:device");









 

In the wrong one:

 

dev_num = find_type_by_name(device_name, "device");









 

 

2. With the switch of the Yocto distro to device tree, the name of driver/trigger changed.

 

This is reflected on http://www.at91.com/linux4sam/bin/view/Linux4SAM/IioAdcDriver

 

echo "fc034000.adc-dev0-continuous" > /sys/bus/iio/devices/iio:device0/trigger/current_trigger
./generic_buffer -n fc034000.adc -t fc034000.adc-dev0-continuous -l 2
The result:


 

Maybe the image that I use (the HDMI demo that peteroakes also uses in his videos) may not have the driver for ADC loaded...

 

According to at91.com, the driver should be at /lib/modules/3.5.0/kernel/drivers/iio/adc/at91_adc.ko

My build is not 3.5.0, but 3.10.0-custom.

I get up to lib/modules/3.10.0-custom/kernel/drivers.

There is no iio in that folder.

 

 

I'l check if there's more info somewhere else...

In /sys/devices/ahb/ahb:apb/fc034000.adc/modalias , I found a reference to the driver name at91sam9x5-adc

But I couldn't load the driver and the generic_buffer tool failed to find that driver too.

 

I've also downloaded nd installed the latet Poky image available from Sama5d4XplainedMainPage < Linux4SAM < TWiki

I've done a file find for all .ko files (I'm searching where the adc_91 would b).

 

find . -print | grep -i '.*[.]ko' > ~/drivers.log










 

The results are attached to the blog (drivers.log). I couldn't find the adc driver.

Just spotted this, it's the Yún but in a smaller form factor.

 

http://arduino.org/products/arduino-yun-mini

 

A000108-ARDUINO_YUN_MINI_flat1.jpgA000108-ARDUINO_YUN_MINI_tri.jpg

Also spotted it's by the Arduino.org team not the Arduino.cc team if you care about such things.

I finally succeeded in measuring blood pressure in an almost reliable way. In this post I will show the results of my experiments

 

In order to determine the law between the value returned by the Force Sensor Resistor and the blood pressure, I run some comparison tests. Basically, I measured my real blood pressure with a normal home medical device (see picture) and associate the readings of the medical devices with the corresponding ADC reading of the FSR.

I made a test on myself (I have a blood pressure of about 130) and my wife (which has a blood pressure of 110)

Here are the data I collected

 

14 - Collected data.png

 

In terms of accuracy, it seems quite good. I applied the following formula to determine the accuracy of the instrument:

 

   14 - Formula1.png

 

I got that the blood pressure reading can vary of less the 10, which is not enough for the MagicHat to be approved for use as a diagnostic device, but it's good enough for a gadget. Also, the design can definitely be improved in terms of sensor selection and mechanical building.

Regarding the selection of the sensor, I probably select the wrong one because its range will allow me to measure blood pressure only up to about 150. IN a next design revision a FSR with a maximum load of up to  3 kilos will be selected

 

Given the above data, I have been able to detemine the following linear correlation between ADC reading and blood pressure

 

  14 - Formula2.png

 

Since I will use Arduino's map function, I need the values corresponding to ADC readings 0 and 1023. So

 

ADC reading = 0 -> Blood pressure = -253,24

ADC reading = 1023 -> Blood pressure = 196,88

 

The above-mentioned results have been obtained in parallel with the choice of the most suitable speed of the elastic rubber string that forces the patient's finger. I need to determine whether the blood is still flowing so I have to wait at least 1.5 seconds to determine whether heart beat is still detectable or not. This requires the movement to be slow. However, it's not very comfortable for the patient if it takes a long time just to measure blood pressure...

The best compromise I found was to move the servo for 20 ms and stop it for 500 ms.

 

Here is a video showing the blood pressure measurement device at work

 

Putting the Arduino Yun to sleep

 

Hans and Matilda thought back to the Golem and how he slept between each activity, that could also work for their Yún.

  

The key things were:

 

  • Turning the Linino power off
  • Turning the Linino power back on
  • Low power on the ATMega side
  • Waking back up.
  • Timers and servo.

 

Poweroff is not enough

 

The Linino O/S uses BusyBox for a lot of the tasks of it's shell. One of these is the "poweroff" command. http://www.busybox.net/BusyBox.html#poweroff

Running this with the multimeter in the loop to check the current we see that running poweroff makes no difference to the current draw, the Yún still takes 200mA.

 

/*
  Running shell commands using Process class.
  based on http://arduino.cc/en/Tutorial/ShellCommands
*/

#include <Process.h>

int ledPin = 13;                 // LED connected to pin 13

void setup() {
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output

  pinMode(A5, OUTPUT);
  digitalWrite(A5, HIGH);    // sets the Linino on

  Bridge.begin();    // Initialize the Bridge

  Process p;
  p.runShellCommandAsynchronously("poweroff"); // Run in background so process returns

  digitalWrite(ledPin, HIGH);   // sets the LED on
}

void loop() {
}









 

Test points and wired control

 

A discussion on the Arduino forum lead to a part of the schematic that controlled the 3.3v regulator. The RT8010 regulator has a two test points TP51 and TP52 (bridged by a 0ohm resistor). The author kindly points out where those test points are located as there's no silk screen indicating which are which. As per the example the corner I/O pin was used, A5.

YunPower-sch.png

YunResetWire.jpg

Retrospectively they remembered that the A5 pin is shared with the I2C bus on the Uno, luckily this is not the case for the Yún.

The software control for this is pretty straight forward too, it can be controlled as a digital pin. You'd want to wait until any writing to disk was complete before powering off so that will need to be factored into the software. Using that control the consumption drops to 30mA.

 

int ledPin = 13;                 // LED connected to pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(A5, OUTPUT);
}

void loop()
{
  digitalWrite(A5, LOW);   // sets the Linino off
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(8000);                  // waits for a 8 seconds
  digitalWrite(A5, HIGH);    // sets the Linino on
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(8000);                  // waits for 8 seconds
}








 

 

You are getting sleepy, very sleepy

But it's possible to even better than that. The commands to put the Arduino to sleep are pretty straightforward even so Hans took the approach of using a library. RocketScream had produced one that made life pretty simple so the code example was extended to incorporate that.

 

//Library from http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/#sthash.PhJ0PF9f.dpuf
#include "LowPower.h"

int ledPin = 13;                 // LED connected to pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  pinMode(A5, OUTPUT);
  delay(25000);                 // Nice long delay to help with reprogramming    
}

void loop()
{
  digitalWrite(A5, HIGH);    // sets the Linino on
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(8000);

  digitalWrite(A5, LOW);   // sets the Linino off
  digitalWrite(ledPin, HIGH);   // sets the LED on

  delay(8000);                  // waits for a second
  digitalWrite(ledPin, LOW);   // both lights off, power and P13

  //Sleep
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}








 

The multimeter uses a different socket for currents over 200mA so a cable swap and photo was taken to get a more accurate reading of the lowest current. For the powerDown the Watchdog timer is used and hence Timer0 which is used for Millis() is turned off and Timer1, used by the Servo() library is also off. This will affect the flashing/colour cycling of the LED and servo so that needs to be factored in the the code.

 

This brings the power down to 2.5mA, approx 80th of the original power required or 33 days of runtime from the battery. Obviously the bursts of activity will bring this down but a week's run time seems achievable.

 

 

IMAG1385[1].jpg

It may also be possible to reduce even more power by permanently turning off those peripherals such as the ADC which are not used although because of the devices used in the project most of the peripherals are used and there may be more effective ways to save power such as minimising the time that the Linino part is powered up.

 

Next: Enchanted Objects Design Challenge - The townsfolk get Rickrolled

 

Reference

 

BusyBox - The Swiss Army Knife of Embedded Linux

Arduino Yun - put linux environment to sleep or halt

Arduino, Zigbee and Embedded Development: Sleeping Arduino - Part 1

http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

Advanced Arduino: direct use of ATmega counter/timers

<avr/power.h>: Power Reduction Management

Sparkfun Adventures in Low Power Land

I'm trying the Buffer and Hardware Trigger  capabilities of the SAMA5D4.

I followed the instructions on IioAdcDriver < Linux4SAM < TWiki, but was struggling with one particular command.

I raised a topic on tha at91.com forum. And resolved it myself.

Sometimes writing down your problem leads to the solution.

 

Instructible

 

You can read my topic on the at91 site to see where I was in trouble.  (jc: At the time of posting this blog, I didn't know yet that I would get the at91.com treatment)
In this blog, I'll post the how-to.

 

Poky (Yocto Project Reference Distro) 1.6.1 sama5d4-xplained /dev/ttyS0


sama5d4-xplained login: root
root@sama5d4-xplained:~# echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en
root@sama5d4-xplained:~# echo "fc034000.adc-dev0-continuous" > /sys/bus/iio/devices/iio:device0/trigger/current_trigger
root@sama5d4-xplained:~# echo 100 > /sys/bus/iio/devices/iio:device0/buffer/length
root@sama5d4-xplained:~# echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable
root@sama5d4-xplained:~#







 

This will start the process. The ADC will now fill the character device /dev/iio:device0 with data.

 

How did I get the magic name "fc034000.adc-dev0-continuous"? It's different than the name "at91_adc-dev0-external" used in the AT91.com instructions.

By fiddling around a lot, and then by submitting the command

 

 

root@sama5d4-xplained:/sys/bus/iio/devices/trigger0# cat name
fc034000.adc-dev0-continuous







 

I still have to write a program that reads the character device.

I have already checked the source of drivers/staging/iio/Documentation/generic_buffer.c but I haven't been successful in compiling it yet.

I'll also need to learn how I can set the sampling speed.

I'd like to get 128 samples in 3.86ms. Check my previous post to understand why.


I hope that by putting this example here, I can help fellow developers started with the on-board ADC.

Image (3).jpg

 

I've mastered the SAMA5D4 just in time for chapter 3 closure. The end of a chapter is the right time to look back and reflect.

 

The world is unfair for people that don't know. I have this powerful board in my hands. And I can't get anything usable out of it. I struggle tremendously and blog (some may say whine) about that.

Then magic happens. The first program compiles. That first program runs. The board says 'hello'.

Having a working program speeds things up. Finally, you can check things out. Change something. Does it still work? No? Why not? Take a step back.

Having that reference point - a working example - is the stepping stone to all further endeavors.

 

Looking back, it's hard to understand why it took that long. In hindsight, it's all not that difficult.

Hindsight is 20/20.

That's why the world is unfair for people that don't know. I know now. The progress in the last few days may be a factor 100 more than what I was able to achieve the previous two months. The blog series tells the story.

 

Photo 19-05-15 20 01 33.jpg

 

 

Finish the Light Organ

 

At very start of the enchanted objects, I stole the Arduino Light Organ design from Daniel Herrera. Unchanged.

Why should I change it? It works perfectly.

But with the SAMA5D4 working, I needed something to practice my skills. And (repeating myself today) having a working example is an ideal starting position.

The Arduino example works. So I ported Daniel's code. I also ported the fft-fix Arduino library that he's using (by itself already a port originating from pre-1990 work of Tom Roberts).

 

In my port, I tried to stay as close as possible to the designs of the original code. I only made tactical changes to make it work on the Xplained board.

You can see that in the attached source code. I've spent 0% to do proper design. When porting something, my favorite way is to stay as close as I can to the original.

I focus on getting it working, not on proper design or reuse. The less confuscated the work, the easier to compare it with the original. Refactoring into proper classes, parameterising and clubbing into reusable parts is for later.

Go ahead and look at the code that I attached to this post. It's very visible that I did the port that way. It's still riddled with debug comments - something that helps me to see where I've done tests and result checking between the Arduino and SAMA5D4. And lots of actions are repeated where a generic function would be appropriate. I may do that later. Or someone else - trying to master the SAMA5D4 - may get their hands dirty and post a sanitized version.

 

 

buckets.jpg

 

Looking at the FFT Results

 

The Organ uses Fast Fourier Transforms to turn the sampled audio signal into buckets of audio frequency spectrum. In this design, 128 samples are turned into 64 buckets, from the low side to the high side.

Bright minds may be able to do the full calculation of the covered bandwidth based on my scope's screen capture.

The high part of the blue signal indicates how long one sample burst takes. And I take 128 samples each time. Post the calculations in the comments, please.

 

SAMA5D4  92ms / 129 samplessamada_sample.jpg

 

ARDUINO 3.86ms / 128 samples

arduino_sample.jpg

I made a mistake here and measured* the inner time between two samples instead of the time to take 128 samples. Below is the old capture that shows the wrong info.

 

This changes the picture a bit, because the sample time is now longer than on Arduino, and I'll have to optimize code instead of adding _nops.

 

sama5d4_nosleep_sampletime.jpg

 

I've recorded the FFT result of a 20Hz, 200Hz, 2kHz a,d 20 kHz signal. My program printed the resulting spectrum array on the linux console.

Here's a chart of the results. It's not yet a very good outcome. 20Hz and 20 kHZ give an outcome as expected, at the low and high side of the spectrum.

But I'm not yet satisfied with how the 200Hz and 2kHz signals are calculated. The 2kHz has peaks lower in spectrum than the 200Hz signal.

Since I used a clean sinus wave as input, this shouldn't happen.

 

 

The plot below, based upon the four tests, shows that the situation is rather fuzzy in the middle part. You can also see a huge peak of the 20kHz signal.

The skew in my results may be based (is very likely based) on the sample speed. In particular the 2kHz signal behaves badly.

I'll try to slow it down* speed it up and get to the same sample speed as the Arduino. That'll give better results.

 

spectrum.jpg

 

These are the captures of the four input signals, taken while doing the exercise:

 

NewFile0.jpg NewFile1.jpg NewFile2.jpg NewFile3.jpg

 

 

 

Side story: Perpetuum Ebner

 

The small workshop that the brothers Steidinger ran was one of the first in Germany to build gramophone 'clockworks'. That isn't strange, because they were clock mechanism makers.

We're talking early 1900's here. The audio industry was still in its very early days. The brothers - both fine craftsmen - made clockworks that could compete with the best. At last their small company was making some money.


But they didn't escape the faith of many brother based companies: they didn't get along.  Both had a juxtaposed view on the business. They didn't get along. It got so bad that the situation couldn't last.

Their separation wasn't friendly. Josef left, and his share of the company was payed out in cogs and springs.

Christian's story is known to all. He created an electrical/spring powered gramophone motor combination (dual drive -> hence the name DUAL). The DUAL brand still brings a tear to the eye of many strong men.


For Josef, it was back to off. With no money and just a pile of spring motor parts a s capital, he rented the sawmill next to Sankt-Georgen station. He calls his humble business "Perpetuum Schwarzwälder Federmotoren und Automatenwerke".


And it's 1911. Another 3 years and it's wartime. Things are about to change for Josef and many other fine mechanics factories in Germany.

 

* I made a mistake in my time measurement for sampling. On the Arduino I measured the time to take 128 samples, on the SAMA5D I measured the time to take one sample.I've corrected the post, but left the original info in place for reference.

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

Image (2).jpg

 

Now that I have my SAMA5D4 development chain under control, it's time to do something with it.

My first attempt is to move the Genuino sketch made for my light organ to the SAMA5D4.

The design has 4 main steps: sampling, applying a Hamming window function, performing a FFT, drive leds

 

Moving C++ code from one environment to another is straightforward. In essence, the only thing I had to do is switch out the Arduino analogread() and digitalwrite() functions for the SAMA5D4 counterparts.

 

This is such a boring exercise that I'm not going to blog about it.

 

Photo 18-05-15 19 22 20.jpg

 

Partly Success

 

The porting exercise went really smooth. My code passed the build in less than an hour. When I ran it on the board, the results were promising.

The sampling worked, and the LEDS were flashing.

 

 

 

But the code failed in a part that I didn't expect: the signal processing part.

I did not get a led pattern that was consistent with the Arduino. Even if I applied a single sinus, all 3 leds were flashing.

With a light organ,you expect that the high led is dim when you apply a low frequency input. On my SAMA5D4, the 3 leds were flashing in a pattern, whatever frequency I applied to the input.

 

Debug Time

 

So it's time to debug. The symptoms point to an issue with the signal processing. So I created a testbed on both systems that just do that.

I give the program a fixed array with samples (the same array on both boards).

Then I check the output after the Hamming function and after the FFT.


Here's a subset of the SAMA5D4 output:

samada fixed sample string:
samples :
0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,-123,-116,-109,-102,-95,-88,-81,-74,-67,...
window :
0,0,0,0,0,0,0,1,2,3,4,5,7,9,11,13,16,19,23,-25,-26,-26,-27,-27,-27,-27,-26,-25,-24,-22,-20,-18,-16,-13,-9,-6,-2...
fft :
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,









And this is the known good result from the Arduino:

Arduino fixed sample string
samples
0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,-123,-116,-109,-102,-95,-88,-81,-74,-67,...
window
0,0,0,0,0,0,0,1,2,3,4,5,7,9,11,13,16,19,23,-25,-26,-26,-27,-27,-27,-27,-26,-25,-24,-22,-20,-18,-16,-13,-9,-6,-2...
fft
9,1,17,226,34,1,26,82,16,9,17,49,2,10,17,5,5,5,13,2,4,13,5,2,2,9,2,1,4,5,1,4,4,1,1,5,1,2,0,5,5,1,2,1,2,1,4,0,4,1,1,5,1,4,1,4,13,2,0,1,5,1,1,1,









It's obvious, isn't it? My port from the FFT lib from Arduino to SAMA5D4 has issues.

Photo 18-05-15 19 23 05.jpg



I'll spend some quality time to see where I made mistakes in the port of that FFT lib. I'll post my findings in a next blog.


For reference, here are the two test beds.


Arduino:

#include <fix_fft.h>


#define MUESTRAS 128           // Numero de muestras para el cálculo de la FFT
#define LOGM 7                 // Logaritmo en base 2 del número de muestras


#define BAJOS_MEDIOS 7         // Nº de banda para el corte entre Bajos y Medios
#define MEDIOS_AGUDOS 35       // Nº de banda para el corte entre Medios y Agudos


#define MAX_PASADAS 10         // Nº de pasadas para el cálculo de los lÃmites


char data[MUESTRAS] = {0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,-123,-116,-109,-102,-95,-88,-81,-74,-67,-60,-53,-46,-39,-32,-25,-18,-11,-4,3,10,17,24,31,38,45,52,59,66,73,80,87,94,101,108,115,122,-127,-120,-113,-106,-99,-92,-85,-78,-71,-64,-57,-50,-43,-36,-29,-22,-15,-8,-1,6,13,20,27,34,41,48,55,62,69,76,83,90,97,104,111,118,125,-124,-117,-110,-103,-96,-89,-82,-75,-68,-61,-54,-47,-40,-33,-26,-19,-12,-5,2,9,16,23,30,37,44,51,58,65,72,79,86,93,100,107,114,121};           // Array con los valores muestreados (parte real)
char im[MUESTRAS];             // Array con los valores muestreados (parte imaginaria)


unsigned char salida[MUESTRAS/2];  // Valores obtenidos de la FFT (espectro de 64 bandas)
unsigned char bajos,medios,agudos; // Valores calculados para cada canal


byte  pasada,                            // nº de pasada para el cáculo de los lÃmites
      acumBajos,acumMedios,acumAgudos,   // acumuladores de veces que se supera el lÃmite
      limBajos,limMedios,limAgudos;      // lÃmites calculados para cada canal




/*
* Funcion que aplica una ventana de Hann a los datos muestreados para reducir el
* efecto de las discontinuidades en los extremos
*/
void aplicaVentana (char *vData) {
    double muestrasMenosUno = (double(MUESTRAS) - 1.0);
  // Como la ventana es simétrica , se calcula para la mitad y se aplica el factor por los dos extremos
    for (uint8_t i = 0; i < MUESTRAS/2 ; i++) {
        double indiceMenosUno = double(i);
        double ratio = (indiceMenosUno / muestrasMenosUno);
        double factorPeso = 0.5 * (1.0 - cos(6.28 * ratio));
  vData[i] *= factorPeso;
  vData[MUESTRAS - (i + 1)] *= factorPeso;
    }
}


void setup() {           
    Serial.begin(9600);


    // Variables para el cálculo de los lÃmites
    pasada = 0;
    acumBajos = acumMedios = acumAgudos = 0;
    limBajos = limMedios = limAgudos = 50;
}


void loop() {

    // Realizamos el muestreo
    for( int i=0; i < MUESTRAS; i++) {
   im[i] = 0;                    // parte imaginaria = 0
    }

    Serial.println(" samples\n");
    for( int i=0; i < MUESTRAS; i++) {
      Serial.print(data[i], DEC);
      Serial.print(",");
    }
    Serial.println(" ---");

    // Aplicamos la ventana de Hann
    aplicaVentana (data);
    Serial.println(" window\n");
    for( int i=0; i < MUESTRAS; i++) {
      Serial.print(data[i], DEC);
      Serial.print(",");
    }
    Serial.println(" ---");

    // Calculamos la FFT
    fix_fft(data,im,LOGM,0);

    // Sólo nos interesan los valores absolutos, no las fases, asi que
    // calculamos el módulos de los vectores re*re + im*im.
    // Dado que los valores son pequeños utilizamos el cuadrado
    for (int i=0; i < MUESTRAS/2; i++){
       salida[i] = data[i] * data[i] + im[i] * im[i];
    }

    Serial.println(" result²²\n");
     for( int i=0; i < MUESTRAS/2; i++) {
      Serial.print(salida[i], DEC);
      Serial.print(",");
    }
    Serial.println(" ---");

}








 


SAMA5D4:

/*
* main.cpp
*
*  Created on: May 16, 2015
*      Author: Jan
*


*
*
*/


#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <math.h>
#include "fix_fft.h"
#include "unistd.h"


using namespace std;


#define MUESTRAS 128
#define LOGM 7                 // Logaritmo en hige 2 del número de muestras


#define BAJOS_MEDIOS 7         // Nº de banda para el corte entre Bajos y Medios
#define MEDIOS_AGUDOS 35       // Nº de banda para el corte entre Medios y Agudos


int data[MUESTRAS] = {0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,-123,-116,-109,-102,-95,-88,-81,-74,-67,-60,-53,-46,-39,-32,-25,-18,-11,-4,3,10,17,24,31,38,45,52,59,66,73,80,87,94,101,108,115,122,-127,-120,-113,-106,-99,-92,-85,-78,-71,-64,-57,-50,-43,-36,-29,-22,-15,-8,-1,6,13,20,27,34,41,48,55,62,69,76,83,90,97,104,111,118,125,-124,-117,-110,-103,-96,-89,-82,-75,-68,-61,-54,-47,-40,-33,-26,-19,-12,-5,2,9,16,23,30,37,44,51,58,65,72,79,86,93,100,107,114,121};           // Array con los valores muestreados (parte real)
int im[MUESTRAS];             // Array con los valores muestreados (parte imaginaria)


#define MAX_PASADAS 10         // Nº de pasadas para el cálculo de los lÃmites


unsigned int salida[MUESTRAS/2];  // Valores obtenidos de la FFT (espectro de 64 bandas)
unsigned int bajos,medios,agudos; // Valores calculados para cada canal


uint  pasada,                            // nº de pasada para el cáculo de los lÃmites
      acumBajos,acumMedios,acumAgudos,   // acumuladores de veces que se supera el lÃmite
      limBajos,limMedios,limAgudos;      // lÃmites calculados para cada canal






int toint(std::string s)
{
    return atoi(s.c_str());
}




/*
* Funcion que aplica una ventana de Hann a los datos muestreados para reducir el
* efecto de las discontinuidades en los extremos
*/
void aplicaVentana (int *vData) {
    double muestrasMenosUno = (double(MUESTRAS) - 1.0);
  // Como la ventana es simétrica , se calcula para la mitad y se aplica el factor por los dos extremos
    for (int i = 0; i < MUESTRAS/2 ; i++) {
        double indiceMenosUno = double(i);
        double ratio = (indiceMenosUno / muestrasMenosUno);
        double factorPeso = 0.5 * (1.0 - cos(6.28 * ratio));
  vData[i] *= factorPeso;
  vData[MUESTRAS - (i + 1)] *= factorPeso;
    }
}


int main() {
  string line;
  int i = 0;








  while(1) {
    // get samples




    for( i=0; i < MUESTRAS; i++) {


//        data[i] = i*14-128;  //Convertimos de 0..1024 a -128..127
      im[i] = 0;                    // parte imaginaria = 0




    }


    cout << "\nsamples :\n";
    for( i=0; i < MUESTRAS; i++) {
      cout << data[i] << ",";
    }
    cout << "\n";






    // Aplicamos la ventana de Hann
    aplicaVentana (data);


    cout << "\nwindow :\n";
    for( i=0; i < MUESTRAS; i++) {
      cout << data[i] << ",";
    }
    cout << "\n";




    // Calculamos la FFT
    fix_fft(data,im,LOGM,0);






    // Sólo nos interesan los valores absolutos, no las fases, asi que
    // calculamos el módulos de los vectores re*re + im*im.
    // Dado que los valores son pequeños utilizamos el cuadrado
    for (i=0; i < MUESTRAS/2; i++){
       salida[i] = data[i] * data[i] + im[i] * im[i];
    }




    cout << "\nresults :\n";
    for( i=0; i < MUESTRAS/2; i++) {
      cout << salida[i] << ","; // this was the biggest mistake. I had a '1' where I should have put an 'i', hard to spot the difference
    }
    cout << "\n";


    break;  // this MUST be removed!!!!!!!!!!!!!!!!!!!!!!!!!!!

  }
  return 0;
}








 

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

C.Defeo's Decorating and Building Merchants

 

Hans and Matilda wanted some sheet metal to build the battery box so popped down to C.Defeo's Decorating and Building Merchants for supplies. The shop keeper advised them that he only had large sheets but he'd cut them for free. He lead Hans and Matilda to the yard out back where the massive sheets of stainless steel were stacked. Hans and Matilda looked up at the sheets and could not work out how the shop keeper was going to move them. He pulled a flute out of his pocket and played a strange tune. From what appeared to be a pile of cement sacks slowly arose a grey brown figure who lumbered over to where they were standing, it was a golem! The shop keeper passed the golem a bottle of ginger beer and he drank it down. The golem turned red then yellow then white and Hans and Matilda realised he was getting very hot so stepped backwards. The golem swiftly and neatly sliced through the metal sheets with his white hot hands before collapsing back onto the cement sacks and falling fast asleep. He does not need much explained the shop keeper, just a few spoonfuls of cement and gingerbeer. "We think he generates acetylene gas which burns internally to produce the heat, not quite sure how it works" he explained, "but it does a good job". "He will now need to sleep for an hour to cool down". The shop keeper explained that he'd been gifted the golem by a Rabbi from Prague in return for some electronic components. Hans and Matilda thanked the shop keeper and returned home with their smaller sheet of metal.

Golem.jpg

 

WARNING!! - Don't mix cement with ginger beer

It probably won't create acetylene but it might create an exothermic reaction or at least make a sticky mess.

 

Bending

Referring to Engineering Workshop Practice 1956 volume III, we can see that the neutral plane for a bend lies 20% of the way through the sheet. Everything on the inside of that will be under compression and everything on the outside will be under tension. We can use this to calculate an allowance for bending.

Bending Allowances from Engineering Workshop Practice Volume IIIBendingAllowancesFromEngineeringWorkshopPracticeVolume32.jpg

The formula for calculating an allowance for bending when the measurements are on the outside of a joint are as follows:

L= A + B - (2 * 0.8)T






 

if the measurements are made on the inside of the joint then it's

L= C + D + (2 * 0.2)T






 

Based on this Matilda sketched a design for the battery box that could be folded out of the metal the golem had cut for them.

 

A box was built based on the sketch and above calculations and the battery fitted perfectly. However, the cable was too short to reach the power board.

Battery Box V1

So a redesign was needed, the side was taken off and it was re-drilled.

BatteryBoxV2.jpg

The rear basement had already been extended to allow for the size of the stack of Arduino and shields. The charging circuit and boosting circuit was moved slightly and the battery and cable now both fitted. The main board was fitted to ensure that there was clearance for all the connectors and that the battery could be removed without needing to disassemble the boards.

BatteryBoxV2Lights.jpgTestFittingTheElectronics.jpg

Some of the cabling was also started with some cables for the LED power and LED made up and a cable for the power also soldered up. The protoshield was wired up with headers for the servo and power supply, for the cables that were undecided they work left long and wrapped over the side of the board. A space was left in the middle of the board for a power mosfet to turn on and off the servo and lighting board.

ProtoBoard.jpgCables.jpg

A productive if not particularly technical week for the project. Next up some more coding and power management and after that if time permits there's still some further enchantments to be applied.

 

Next: Enchanted Objects Design Challenge - Sleeping Golem

I held off my review for more than a month.

I have read the specs and was quite impressed.

Then I reviewed the SAMA5D4 Xplained Ultra Evaluation Kit USER GUIDE. And I had mixed feelings after that.

Hardware wise, this is a great document. Software wise, it's not good.

 

Photo 16-05-15 16 18 16.jpg

 

Scoring

Product Performed to Expectations:10
Specifications were sufficient to design with:10
Demo Software was of good quality:yes, but hard to find and apply
Demo was easy to use:No
Support materials were available:yes, but hard to find and apply
The price to performance ratio was good:10

TotalScore:hard to give, see review

 

I've spent two months investigating the board, the available information, and the look and feel of the community around it.

 

First a bit of background on my skills: I know electronics, microcontrollers and processors, have unix/linux, rtos  and C++ experience, can program several ARM flavors. Know build systems, IDEs and tool chains

 

I have no prior experience with developing for high performance embedded systems like this SAMA5D4.

I have difficulties getting started with datasheets only. I need working examples and how-to guides to step on the learning curve. I have difficulties getting started if I don't have a working example that I can refer to.

 

All further comments have to be seen with that background in mind.

 

 

The ARM Processor, Peripherals and the Board

 

I only have one word for that: impressive. This is a very decent offering, able to run high demanding designs, bare metal and on an OS

Lots of processing power, a great platform. The processor by itself has a wealth of peripherals. I'm not going to enumerate them here; please refer to http://www.atmel.com/products/microcontrollers/arm/sama5.aspx#SAMA5D4_series

And they worked perfectly, as expected.

Same for the board. Once loaded with a decent Linux distro, it was straightforward to connect to it and use it. Small minus points for shipping it with a distro that doesn't support SSH.

I've looked at the suggested applications for this processor Atmel's website. and I'm confident that this processor has all the specs to live up to that.

 

Operating System Support

 

That's just great. The board can run Android, Window and Linux.

I've only tried Linux, but seen evidence of the other two on the web.

The complexity of the processor and the peripherals imply that an OS is needed for all but the most hardcore situations.

Being able to run at least three of them shows that Atmel did it right here.

 

Getting Started and Developing  for the Processor and Board

 

I'm going to skip all the ranting here (also deleted the comment on first step: install Atmel Studio 6x).

Just this: if you follow the steps of the leaflet in the board and the Getting Started  links on Atmel's website, you'll end up frustrated.

Nothing there will lead you to a working example. Full Stop. Unless you're already an expert.

 

I have a hard time to explain how difficult it was for me to get a tool chain set up, examples compiled, and get them loaded and executed on the board.

In hindsight, all I did was already documented on the web. Nothing I did successfully hasn't been done by someone else before. But the Getting Started documents and links do their very best to send you astray.

Google doesn't help the starter either. It returns results, but it takes an experienced eye to filter wrong advice from right advice. My calendar tiched more than 60 days before I was capable of seeing that difference.

My computer has approximately 1GB of needlessly installed software and non-working examples.

Atmel, please, get a decent learning trail out, and use that as the starting point in your leaflet.

element14, please convince road test and design challenge suppliers to have decent starter doco out. It avoids counterproductive campaigns.

I challenge anyone to just follow the starting points from either Atmel's site or the Getting Started Guide and end up with a working example.

Post success in the comments here and I'll revise my opinion.

 

 

Demos

 

Just look at peteroakes's videos and stand in awe. The processor can handle a lot.

And the demos show that. Just look at the video streaming capabilities, and appreciate the processor power needed to do that.

On the other hand, you'd better have the exact right display and touch screen, or the comments from the section above apply.

Similarly, I was not able to load and run the bare metal examples that are posted on the Atmel SAMA5D4 landing page on my own.

An ascii readme with instructions from source to 'running the executable on the board' would have taken less than 2 KB. It's doable. Someone on the support forum explained it to me in 8 steps;

 

Community Support

 

I have a very mixed feeling here. There is the AT91 forum. There's the Linux, Android and Windows sub-area on AT91.

And there's loads of great info available over there.

Now that I understand more on the subject, I'm able to find and appreciate the wealth of info. As a starter I was 100% lost.

I submitted a post on the AT91 forum, and I was helped excellently. On the other hand I also saw posts of other starters that turned ugly - one of the reasons why I waited long to ask for advice there.

For an advanced area like programming such an advanced  embedded processor (bare metal or linux), it would be great if the experts would recognize the difficulties that a starter can have.

It 'll be those starters that will be advocates in favor of the product later.

 

added 20 May

I held of posting to at91.com for a long time, because oft the tone used.

Once I started posting a few days ago, I set a counter for myself on how long it would take for blue_z to come in with a you should have.

8 posts.

 

added May 27

There's new content posted on AT91.com. For instance, the ADC Driver page now has a very good explanation and instructions:

IioAdcDriver < Linux4SAM < TWiki

 

Conspiracy Theory

 

I think that Atmel has training documents for this board. I've seen one for the SAMA5D3. It was great (really!), but only after a road tester got in touch with a representative from Atmel, it was released to the community.

My suspicion says that there's a similar document for this board. If Atmel uses this board to train customers, there has to be a similar document.

I have a same comment on the demos. They'll do great on faires. For the evaluation user it isn't evident to find them and to load them. Peter's videos come to the rescue.

Not publishing such a document so that road testers and design challengers can use it, is the reason why I called Atmel reckless in a previous comment.

I think that I would have been able to do what I did after 2 months on day 1, if only there was a guide to take the humble beginner by the hand.

Other companies can do that for similar complex subjects.

This board is so great. And several of the reviewers on element14 have made innovative designs with lesser controllers.

I can only dream of what all those motivated road testers and reviewers would have created if they would have had a good tutorial to get that blue LED blinking.

 

Summary

 

It's a great processor, and a board with loads of possibilities. Loads of options. Nice PCB design. Very high quality.

Never ever have I experienced a bug. And as electronics aficionado, I stand in awe when I hold it it my hands.

Should you use the SAMA5D4:?  Yes, definitely it is an ARM that lives up to its specs, and it sports great peripherals.

Should you use the Xplained Ultra board? Yes, if you already have skills in this segment or if you are very stubborn. No if this is your entry point to learn embedded linux.

It's a great development kit, and it would excel in its segment if the public training materials would guide you to a repeatable path to wisdom.

 

Atmel is playing in a market with loads of competition here. There are several other suppliers that have ARM offerings in this segment. Silicon wise, Atmel is up there with the biggest. Community wise, there's a work to be done.

 

tl;dr

 

Great processor, great board. With a reasonably good document I would have been on day 2 where I am now after 60 days. Think twice before posting on the at91.com forum.

I'm making steady progress on this drizzly day.

I have my first C++ linux program running that samples the an ADC pin on the SAMA4D4 Xplained Ultra Board.

 

In the mid 90's, I was a C++ software developer. Around that same time, the standard template library (STL) came into fashion.

It's great to use it once again.

 

Photo 16-05-15 16 31 07.jpg

 

Getting the ADC values

 

Once again, this is inspired by peteroakes's work on this board, SAMA5D4 Xplained Ultra - Tips and Tricks #2 - Using the built in IO and external devices.

I'm using a very similar setup as Peter, but instead of using the Linux command line to read the sample results, I've written a C++ program.

But we're both triggering a sample and reading results by accessing /sys/bus/iio/devices/iio:device0/in_voltage0_raw.

 

The schematic is very simple: a potentiometer with both ends connected to ground and 3.3V of the Xplained board. The wiper goes to A1.

To make things funny, A1 is analog port 0 in the linux mapping. (I don't know yet what A0 is, but it has a digital signal on it when I sample it with my scope.)

 

The program is cross-compiled using the GNU toolchain on a windows machine, loaded to the linux root user's home folder, and executed.

It shows a sample result in the terminal window every second.

I haven't used any of the Atmel libraries. All is done via standard file access.

 

#include <iostream>
#include <fstream>

using namespace std;

const char fileName[] = "/sys/bus/iio/devices/iio:device0/in_voltage0_raw";

int main() {
  string line;
  while(1) {
    ifstream myfile(fileName, ios::in);

    if (myfile.is_open()) {
      while (getline (myfile,line)) {
        cout << line << '\n';
      }
      myfile.close();
    } else {
      cout << "Unable to open file " << fileName << "\n";
    }
  }

  return 0;
}

 

That's the whole program. After compilation, linking, uploading and setting the executable flag, here's what it looks like in the terminal:

 

 

The value changes when moving the potentiometer wiper.

Image.jpg

 

 

My lab doesn't have a wired network. And that makes it difficult to develop on the SAMA5D4 Xplained Ultra board.

The only way I am able to move compiled binaries from my Windows development machine to the board is via SCP.

But that meant that I have to connect the board to the wired network in my living room.

 

In this post you can read my successful work to enable file transfer over the USB connection. I can now transfer my programs to the board in my lab.

No need to take it out of the circuit under construction anymore.

 

 

Tera Term: Terminal Program with File Transfer

 

Tera Term is a terminal program, comparable to PuTTY and HyperTerminal. It has file transfer capabilities, and supports multiple protocols.

The  modus operandi isn't difficult. You first log on to the board with the serial port, similar to PuTTY.

Once connected, you have to adapt the Serial Port attributes for the Xplained Ultra.

 

 

Most likely this can be set in a configuration file, but I haven't looked into that yet.

On the linux prompt, log on as root.

 

Start the XMODEM listener

Prepare your linux session for file receiving by entering the rz command:

 

rz -e -b -X HelloARMWorld



 

rz is the file receive command.

-e takes care that all special commands are properly escaped

-b does a like for like (binary) transfer

-X selects the XMODEM protocol

 

Send the file

On the Tera Term menu, select File -> Transfer -> XMODEM -> Send...

 

A dialog pops up to select the source file. Once you selected the file, a progress bar appears:

 

 

When that transfer is finished, the file is available on linux.

The only thing we have to do is make it executable:

chmod +x HelloARMWorld



and run it:

./HelloARMWorld



 

 

Done !

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

... way down south.

I avoid blogging about my job. I'm making an exception for this one time because it's going to impact the challenge:

I just came to know that I'll be off to Johannesburg, South Africa, for a work assignment soon. That means that I'll be without lab for most of the time.

 

I'm excited about the assignment and the work location. The impact to this project here is unknown. In any case, the job comes first.

 

Tomorrow Never Knows.

20150515.jpeg

I'm continuing with the scope creep exercise.

As a preparation to make my Analog Shield talk to the SAMA5D4, I've been testing the on-board ADC functionality.

I've also measured the AC and DC signal path from signal source to ADC chip in.

 

setup.jpg

 

The Digilent / Texas Instruments Analog Shield ADC circuit

 

Our converter is the Texas Instruments ADS8343 16-Bit, 4-Channel Serial Output Sampling Analog-To-Digital Converter.

 

adc.png

The signal goes through 2 opamps before entering the ADC, and it is set up in such a way that both positive and negative signals can be sampled.

The first opamp, TI's LM837 Low Noise Quad Operational Amplifier.

It has two duties.

It more than halfs the input signal (0.4 amplification).

And it adds a DC component to the signal.

 

Check out the schematics for the Analog Shield for the voltage reference design. The circuit, has been taken from TI's application note "Miro Oljaca and Bonnie Baker - How the

Voltage Reference Affects ADC Performance Part 3 - Analog Applications Journal (4Q 2009)".

 

With my so-so voltmeter I measure a DC out perfectly matching what's sent at the input (2.03V).

The output is balancing around 2.86mV with floating input (this will be the case in my situation, where I have a reasonable high impedance input).

 

I've added a dc blocking cap at the input because the setup with the first opamp would inject DC into the pickup coil of my turntable.

The signal, clamped on positive and negative side by a pair of Schottky diodes (SDM40E20LS) in a single package, is sent to a second opamp buffer: TI's OPA4322 rail-to-rail CMOS opamp.

That one drives the signal, unchanged, to the ADC.

 

Sampling

 

I've used the sampler with the internal power supplies on the analog shield to measure DC capabilities. That's all very easy:

 

I mounted the shield on the Arduino UNO that came with the challenge, and connected each of the voltage outputs of the shield's power supply connector in turn to the ADC0 input of the ADC connector.

 

The sketch was only a few lines of code:

#include <analogShield.h>
#include <SPI.h>

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned int sensorValue = analog.read(0);
  Serial.println(sensorValue);
  delay(100);
}




 

All worked fine except for one thing. I imported the Analog Shield library with the new Arduino lybrary manager, and I had to add this line to the if defined(__AVR__) section of the library's header file to get a correct compilation:

 

#include <SPI.h>




 

Arduino IDE's include strategy be darned *%$£§@.

 

As a second exercise I connected my turntable to the input and modded my Digital Light Organ Enchantment to work with the Analog Shield ADC.

There was little to change. As a challenge for myself, I added a simple input range optimizer.

 

In the light organ, the sampled input data is sent to a FFT lib to filter out the highs, mids and lows.

The library range is -128..127. My samples are 0..65535.

But since the range of my audio signal falls roughly between 20000 and 55000 (I sampled the data to check the range, but since my code is dynamically setting it, the actual limits don't really matter), I loose significant resolution if I mix the full range down to -128..127.

To limit the loss in resolution, I calculate the division factor in my code as a function of the effective minimum and maximum.

I set them at he starting limits of 20000 and 50000. If the signal drops below or peaks above, I adjust the range.

I also added a range aging mechanism. The range narrows in each loop of my code. So the upper limit ages towards the lower limit and vice versa.

Only to be pushed back up or down by the signal's peaks.

The aging is there to prevent that a loud part of the signal puts the limits out and spoil the fun any silent part coming later.

 

Here's a few highlights of the code adaption.

 

The preparation and declarations:

 

// http://arduino-guay.blogspot.com.es
// adapted to ti/digilent analog shield jc
//...
#define AUDIO_MINIMUM 20000U
#define AUDIO_MAXIMUM 55000U

void setup() {                
    //...
    // jc removed for analogshield    analogReference(INTERNAL);
    //...
}



 

 

The loop

 

void loop() {
  unsigned int sampleValue = 0U;

  // signal window
  static unsigned int maxi = AUDIO_MINIMUM;
  static unsigned int mini = AUDIO_MAXIMUM;
  unsigned int range = 0U;
  //...



 

 

Range aging:

 

  //...
  // age the signal window. Let the signal range slowly go narrow, so that the signal peaks can drive it to a good range
  if (maxi > AUDIO_MINIMUM) {
    maxi--;
  }
  if (mini < AUDIO_MAXIMUM) {
    mini++;
  }
//...



 

 

Sampling

 

       sampleValue = analog.read(0);



 

 

Range calculation and limits adjust

 

     if(sampleValue>maxi) {
         maxi =  sampleValue;
       }    
       if(sampleValue<mini) {
         mini =  sampleValue;
       }
       range = maxi - mini;



 

 

Down-calculation to -128..127

 

       data[i] = (sampleValue/(range/256)-128);
//...
}



 

As always, the chances for bugs in my calculations are high. Beat me when I goofed up.

 

Photo 15-05-15 19 31 07.jpg

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

As mentioned in a previous installment Hans was having some trouble installing the secure version of the requests module for python, it didn't matter what he tried there always seemed to be something that needed a different version of a tool installing or a script that did not want to run correctly. So Hans took some steps back and wrote the code to get the weather instead.

 

Thinking about the reason for using requests in the first place it was to make the code simpler, however the function to call the API was small and self contained so Hans realised he could swap that out with pycurl instead. So he installed the relevant packages.

 

opkg update
opkg install python-openssl
opkg install python-curl







 

And updated the Python script to use pycurl, he coded it so that either version could be used by swapping out call_api. For the pycurl commands to work an old version of the call was needed, c.setopt(c.WRITEFUNCTION, r.write) rather than c.setopt(c.WRITEDATA, r).

 

from StringIO import StringIO
import pycurl
import json, sys, urllib, urlparse

def get_location():
    with open('/etc/WeatherAPI.conf', 'r') as f:
        location_name = f.readline()
    f.close()
    return location_name


def build_url(location):
    url = "https://query.yahooapis.com/v1/public/yql"
    q = "select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text = '" + urllib.quote(
        location) + "') and u='c'"
    params = {'q': q, 'format': 'json', 'env': 'store://datatables.org/alltableswithkeys'}

    url_parts = list(urlparse.urlparse(url))
    query = dict(urlparse.parse_qsl(url_parts[4]))
    query.update(params)

    url_parts[4] = urllib.urlencode(query)

    return urlparse.urlunparse(url_parts)

def call_api(url):
    r = StringIO()
    c = pycurl.Curl()
    c.setopt(c.URL, url)
    c.setopt(c.CONNECTTIMEOUT, 10)
    c.setopt(c.TIMEOUT, 60)
    c.setopt(c.WRITEFUNCTION, r.write)
    c.perform()
    c.close()
    return r.getvalue()

def map_code(code):
    # Map condition codes to expected precipitation
    # https://developer.yahoo.com/weather/documentation.html
    # 1 = very sunny, 3 = changeable, 5 = very rainy
    codes = {'0': {'n': 'tornado', 'p': '3'},
            '1': {'n': 'tropical storm', 'p': '5'},
            '2': {'n': 'hurricane', 'p': '5'},
            '3': {'n': 'severe thunderstorms', 'p': '5'},
            '4': {'n': 'thunderstorms', 'p': '5'},
            '5': {'n': 'mixed rain and snow', 'p': '5'},
            '6': {'n': 'mixed rain and sleet', 'p': '5'},
            '7': {'n': 'mixed snow and sleet', 'p': '5'},
            '8': {'n': 'freezing drizzle', 'p': '5'},
            '9': {'n': 'drizzle', 'p': '4'},
            '10': {'n': 'freezing rain', 'p': '5'},
            '11': {'n': 'showers', 'p': '4'},
            '12': {'n': 'showers', 'p': '4'},
            '13': {'n': 'snow flurries', 'p': '4'},
            '14': {'n': 'light snow showers', 'p': '4'},
            '15': {'n': 'blowing snow', 'p': '3'},
            '16': {'n': 'snow', 'p': '4'},
            '17': {'n': 'hail', 'p': '4'},
            '18': {'n': 'sleet', 'p': '4'},
            '19': {'n': 'dust', 'p': '3'},
            '20': {'n': 'foggy', 'p': '4'},
            '21': {'n': 'haze', 'p': '3'},
            '22': {'n': 'smoky', 'p': '3'},
            '23': {'n': 'blustery', 'p': '3'},
            '24': {'n': 'windy', 'p': '3'},
            '25': {'n': 'cold', 'p': '3'},
            '26': {'n': 'cloudy', 'p': '3'},
            '27': {'n': 'mostly cloudy (night)', 'p': '3'},
            '28': {'n': 'mostly cloudy (day)', 'p': '3'},
            '29': {'n': 'partly cloudy (night)', 'p': '3'},
            '30': {'n': 'partly cloudy (day)', 'p': '3'},
            '31': {'n': 'clear (night)', 'p': '1'},
            '32': {'n': 'sunny', 'p': '1'},
            '33': {'n': 'fair (night)', 'p': '2'},
            '34': {'n': 'fair (day)', 'p': '2'},
            '35': {'n': 'mixed rain and hail', 'p': '4'},
            '36': {'n': 'hot', 'p': '1'},
            '37': {'n': 'isolated thunderstorms', 'p': '4'},
            '38': {'n': 'scattered thunderstorms', 'p': '4'},
            '39': {'n': 'scattered thunderstorms', 'p': '4'},
            '40': {'n': 'scattered showers', 'p': '4'},
            '41': {'n': 'heavy snow', 'p': '5'},
            '42': {'n': 'scattered snow showers', 'p': '4'},
            '43': {'n': 'heavy snow', 'p': '5'},
            '44': {'n': 'partly cloudy', 'p': '2'},
            '45': {'n': 'thundershowers', 'p': '5'},
            '46': {'n': 'snow showers', 'p': '5'},
            '47': {'n': 'isolated thundershowers', 'p': '4'}}
    state = codes.get(code)
    if not state:
        raise RuntimeError('Unknown weather code returned')
    return state['p']


def parse_weather(json):
    text = json['query']['results']['channel']['item']['condition']['text'].replace(",", " ")
    code = map_code(json['query']['results']['channel']['item']['condition']['code'])
    temp = json['query']['results']['channel']['item']['condition']['temp']
    return {'text': text, 'code': code, 'temp': float(temp)}


def main():
    try:
        loc = get_location()
        weather_url = build_url(loc)
        r = call_api(weather_url)
        j = json.loads(r)
        weather = parse_weather(j)

        print 'OK!,%s,%s,%4.2f' % (weather['text'], weather['code'], weather['temp'])

        return 0

    except Exception, err:
        print 'Err,%s,0,0.0' % str(err).replace(",", " ")
        return 1


if __name__ == '__main__':
    sys.exit(main())







 

The first run reported an error with not being able to verify the certificate so he re-installed the certificates using a slightly modified script that downloaded the certificates from OpenWRT, as the Yun pakcage repository does not seem to have these.

 

#! /bin/sh
OPENSSL=/usr/bin/openssl
CERTDIR=/etc/ssl/certs

opkg update
#opkg install ca-certificates
wget http://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/packages/base/ca-certificates_20141019_ar71xx.ipk  
opkg install ca-certificates_20141019_ar71xx.ipk

# Install openssl-util if need
[ ! -f ${OPENSSL} ] && opkg update && opkg install openssl-util

for CERTFILE in ${CERTDIR}/*; do
    # create symbolic link from hash
    echo -en "Certificate ${CERTFILE##*/}\n generating hash: "
    HASH=$(${OPENSSL} x509 -hash -noout -in ${CERTFILE})
    echo "$HASH"

    # handle hash collision
    SUFFIX=0
    while [ -h "${CERTDIR}/${HASH}.${SUFFIX}" ]; do
        let "SUFFIX += 1"
    done

    echo "linking ${HASH}.${SUFFIX} -> ${CERTFILE##*/}"
    ln -s ${CERTFILE##*/} ${CERTDIR}/${HASH}.${SUFFIX}
done

rm ca-certificates_20141019_ar71xx.ipk







 

Running it a second time produced a result. Hans had never been so happy to know that it was Mostly Cloudy in Chicago, IL.

MostlyCloudy.png

Next: Enchanted Objects Design Challenge - The Glowing Golem and shiny battery box

In this post we will have a look  at how the client side of the web application is implemented

For the web client I used the Angular JS framework and the graphical components made by Telerik. This components are not free (I have a licence since I used those components at work, but they can be easily replaced with free and/or open source components)

 

The most interesting part is how the web socket is created and how data is processed to update the web page.

The web socket is created by passing the url of thehost we want to connect to (in this case I am using the default IP address of Arduino Yun

 

                $scope.dataService = new WebSocket('ws://192.168.240.1:3000');

 

Then, we can add the handlers for the events we are interested in. For example, I am interested to handle the "data received event"

 

                $scope.dataService.onmessage = function(event){ 
                       console.log('data ' + event.data);
                       $scope.updateData(JSON.parse(event.data));
                };

 

Eventually, you could also get notification whenever the connection is open or when an error occurs

 

$scope.dataService.onopen = function(){ 
                       console.log('Hello');
                };                                            
 $scope.dataService.onerror = function(){ 
                       console.log('Error');
                };

 

The $scope.updateData(data) is a function that takes care of updating the widgets with the data received on the web socket. The JSON.parse(event.data) function creates a Javascript object from the string received. The object structure will look like this

 

{

temperature: 37,

pressure: {min: 0, max: 120},

bpm: 62,

pulse: [0,0,0,...,0,0];

}

 

This object is passed to the   $scope.updateData function

 

$scope.updateData = function(data)
 {
 if (data.temperature)
 $("#gauge_temp").data("kendoLinearGauge").value(data.temperature);

 if (data.pressure)
 {
 $("#bpmin-value").val(data.pressure.min);
 $("#bpmax-value").val(data.pressure.max);
 $("#gauge_bp").data("kendoRadialGauge").value(data.pressure.max);
 }

 if (data.bpm)
 { 
 $("#read_bpm").each(function() {
        $(this).industrial(data.bpm);
 });
 }

 if (data.pulse)
 { 
      if ($scope.pulse.length + (data.pulse.length/10) > 50)
      {
        var howMany = ($scope.pulse.length + (data.pulse.length/10)) - 50;
        $scope.pulse.splice(0, howMany);
 }                    
           
 console.log('Adding values..' + data.pulse.length);
 for (var i=0; i<data.pulse.length; i+=10)
 {
        $scope.pulse.push({ value: data.pulse[i] });
 }
 }
 };

 

The final result is shown in the following video

 

I've mentioned before that we are not the only ones determined to enchant some objects.

 

Simon Morris has made floating lightbulbs powered by induction.

 

 

via:

http://makezine.com/2015/05/03/making-lightbulbs-float/

crjeder

Next Road Block

Posted by crjeder May 13, 2015

I've identified an other road block:

The RGB LED Lighting Shield uses 10-bit I2C addresses! I found a good explanation here. Should not be a big problem but standard tools as i2cdetect only work with 7-bit addresses. Let's how it works.

20150514.jpeg

 

 

Scope creep. It's the dead of every single project.

Still I let it seep into my design.

Because I received something that I enjoy spending time on.

 

 

And yes. The date is wrong in the picture above. One of my kids has already removed May 13 to read the joke on the backside..

Photo 12-05-15 16 01 49.jpg

 

 

 

 

The Digilent / Texas Instruments Analog Shield

 

Loads of fun to be had! This educational board has analog goodies on it.

And since my (not really mine) turntable is all analog, I feel that there's a good mix in the making.

 

My dream is to build something cool with this board mounted on the Atmel SAMA5D4 Xplained Ultra.

Whatever that may be.

It is possible that the end result has little relation to my submitted idea, but I'll take that as a plus .

 

Why this scope creep?

In my work life, I steer away from scope creep as much as I can. But this is not work.

In this design contest, I want to have plain fun. But I also want to do something relevant.

I've been struggling to find good use for the SAMA5D4. I know it's a great platform. And I had great plans for it.

But I also realize that I won't fully tame it within the timelines for this project. I won't be able to use it to its full capacity.

But I got myself to some level. I can compile my own c++ linux code.

My first idea after I realized my skill gap with the board was to replicate the light organ and servo motor part of my design on the SAMA5D4.

But that's sad, isn't it? If the only thing you can do with the Xplained Ultra is replicating something that the Arduino UNO with an ATMEL ATMega does just fine?

 

And that's where the Analog Shield comes in handy. It allows me to do something new.

And to learn something new, and to get a purpose for the SAMA5D4.

It's not going to be rocket science, but a part of my personal (publicly shared ) learning track.

 

What's on the Shield

 

It's a mix of Analog to Digital, Digital to Analog, and power supply circuits.

I'm going to focus on the ADC first. It's a 16 bit converter with four channels. And it supports SPI.

I'll do 'something' with my audio signal and that ADC converter.

If I have success, I'll have a look at the DAC. That one is also 16 bit with 4 channels.

 

At the moment I have no idea for the two power supplies. Both can go positive and negative.

One is fixed +/- 5V. The other one is variable +/-7.5V.

 

1. Analog to Digital Converter (ADC) Header

2. Digital to Analog Converter (DAC) Header

3. Power Header

4. Voltage Select Jumper

5. Variable Voltage Potentiometer

 

 

 

 

The only promise I make at this point is that I'll do my best to make something interesting out of it. And that I'll share success + failure on the blog.

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

So the genie decided that it would be fun to start learning how to use new tools and build things instead of tiring himself out with using all of his magic. He hopped out of his cramped and cluttered lamp and decided he would need an area to store some of his items so that he had more space in his lamp. He decided to build a shed. But so it would look nice, no matter the surrounding he also decided to use a color that went well with all styles, white (*cough* ivory). He slaved for 5 hours and 11 minutes building it. But when it was over he was pleased with the results and immediately began moving items in.


image3.JPG

                                                     The roof and the floor separated

image4.JPG

                                                          Together, but empty

image1.JPG

                                                                   Perfect fit!

image2.JPG

                                                    My first ever 3D print!

 

I apologize for the funky orientations but I can't seem to rotate them in here. Also I still need to drill holes in the four corners so the top can be screwed in to the bottom piece!

I am one of those who took the challenge to use the SAMA5D4 from the kit. My take on it is to boot using nfs mounted root file system. This would have the advantage that I would have as much space in the root file system as I need and that I could easily do changes to the rootfs without flashing the board again and again. This should dramatically speed up the development process.

Obtaining the rootfs Image

 

I'd like to use one of the large standard distributions so I look for a debian port to the arm architecture and fortunately it exists. But from there I can only download iso install images. Not exactly what I want. But to my rescue armhf.com provides a rootfs image without kernel (scroll to the bottom of the page). That's important, because in this way I can use the kernel provided by atmel which includes the correct drivers.


NFS Server

 

I have a synology NAS which provides network storage over several protocols which include nfs. So I only have to unpack the rootfs to /volume1/rootfs/SAMA5D4 and tell the server about it. For the NAS a gui is provided.

If you want to use a generic linux server just add a line to /etc/exports:

/volume1/rootfs/SAMA5D4 all(rw,sync,root_squash,no_subtree_check)

After this restart the nfs server (on synology this happens automatically):

exportfs -a

service nfs-kernel-server restart

Now the rootfs is provided via nfs.

 

Das U-Boot

 

(German for "the submarine")

Das U-Boot, the Universal Boot Loader is the boot loader used by the system image with which the SAMA5D4 Xplained board ships. To change anything in the boot process I have to change the configuration of U-Boot. This is done on it's own command line which is reached by interrupting the boot process:

 

Hit any key to stop autoboot: 0

=>

Now it's time to look at the documentation. To mount the rootfs through nfs the kernel parameters have to point to the nfs server.

The relevant kernel parameters are taken from https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt:

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>

To set this parameters use:

=> printenv bootargs

bootargs=console=ttyS0 <......>

 

=> setenv bootargs 'root=/dev/nfs nfsroot=192.168.1.1:/volume1/rootfs/SAMA5D4 console=ttyS0 <......> ip=dhcp'

Printing the content of the bootargs variable is necessary to append the old value to the new one with cut and paste.

Changes are made permanent by 'saveenv' but this should be done after testing.

Now boot the board with the 'bootd' command.

creating NFS state directory: done

starting statd: done

NFS daemon support not enabled in kernel

 

The kernel is compiled without nfs support. In order for this to work I would need to compile a new kernel. That's bad since time is allready short. I have to find an other solution. Thanks to peteroakes, clem57 and jancumps there is at least a way to use the board. I'll try this route next.

20150512.jpeg

 

I've done many attempts to build and execute my own C program on the atmel sama5d4 xplained ultra board.

 

Thanks to the tutorial on mikrocontroller-software.de, I was able to cross-compile and run my first binary (see post 13: Breakthrough - Run my own C++ Program on the SAMA5D4).

 

 

That same mikrocontroller-software.de has also helped me with the next step: blink the led.

 

 

Getting to Blinky

 

I've stolen the title of this section. Getting a led to blink is the "Hello, world!" of the embedded world.

Usually, this is the first exercise you do right after unboxing.

It took me so long to get here because of several reasons. I knew that the example that I'm trying here was around, but I held off trying it out.

Grease up your German skills once more, and visit Atmel SAM5D4 LED D8 blinken lassen Beispiel [ATMEL® SAMA5D4 Xplained Ultra Getting Started] .


File Handle based I/O with Linux


I'm still struggling with the example.

The author uses the file handles that are created in the linux distro to talk with the peripherals. That part I get.

But I don't know yet why there's both a call to set the GIO ("/sys/class/gpio/pioB3/value") and a call to set the brightness as below:


        if(true==on)
        {
        LinuxFile("/sys/class/leds/d8/brightness",
                O_WRONLY).Write("1");
        std::cout << "Switch LED on";
        }
        else
        {
            LinuxFile("/sys/class/leds/d8/brightness",
                            O_WRONLY).Write("0");
            std::cout << "Switch LED off";
        }





I'll have to do some more reading, learning and and testing to understand that.

I'm a bit in a disadvantage there, because I don't have wired network in my lab. The board is dangling from my router/wifi device in the living room .


Anyway, the program works. In debug mode, it compiles to 101 KB.

In the console, this is how the execution looks like:


The blue led on the board blinks:


blueblink.png


Customer Action Photo:


Photo 12-05-15 15 59 47.jpg



 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

A useful presentation on securing your devices

 

  1. Defining the Internet of Things (10:27)
  2. Unprotected devices will be attacked (13:15)
  3. Encryption (15:46)
  4. Single security model for all communications (17:56)
  5. Access control (20:13)
  6. Tracking device metadata (21:14)
  7. Provisioning in the field (22:38)
  8. Firmware updates in the field (24:07)
  9. Compliance with regulations (25:15)
  10. Reinventing the wheel (26:17)

 

http://blog.atmel.com/2015/05/04/the-10-challenges-of-securing-iot-communications/

While struggling to complete the blood-pressure measurement device, let's have a look about how to show measured value

 

In this project, measures will be communicated to the user in two way

  1. through a web interface that can be accessed by any device running a web browser
  2. through a Text-To-Speech engine

 

As I'm still waiting for the components required to build the Text-To-Speech engine, in this post I will focus on the web interface

The web interface will be built using node.

The first step to take is to install node and expand the memory. I followed this tutorial to accomplish this task. All steps completed with no issues (except you have to change to opkg configuration file by replacing the line

src/gz barrier_breaker http://download.linino.org/dogstick/all-in-one/latest/packages/

with

src/gz barrier_breaker http://downloads.arduino.cc/openwrtyun/1/packages

 

 

As I like experimenting new approaches to the a problem, I decided to move away from the typical solution based on periodic poll to update the values on the web interface and use web sockets instead. The data flow is shown in picture below

 

12 - Web interface.png

 

Basically, whenever the Atmel 32U4 has updated data, it sends such data (formatted as a JSON document) to the node application that is listening on port /dev/ttyATH0)

If a client is connected on a web socket, the node application sends the same document on the web socket. Upon receiving new data, web client update widgets accordingly

This is not the best approach from a software-engineering point of view (I broke the separation-of-concern principle as the Atmel32U4 should be unaware of data format used by the web client) but it's quick and easy  to implement and to understand

 

First of all, a node package needs to be installed in order to access the serial port from the node application itself

 

opkg node-serial


 

In the node application, first of all we need to create a listening web socket, that passively waits for a client connection.

 

_ws = null;
var wss = new webSocketServer({server:server});
wss.on('connection', function(ws) {
  _ws = ws;
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });
  ws.on('close', function(message) {
    console.log('closed');
    _ws = null;
  });



 

Then, we need to open the serial port that listens for data from Atmel 32U4.

 

_data = "";
yunPort = new serialPort.SerialPort('/dev/ttyATH0', { baudrate: 115200 });
yunPort.on('data', function(data) {
  console.log('data ' + data);
  if (_ws)
  {
    _data = _data + data;
    if (_data.indexOf("\r\n") > 0)
    {
      _ws.send(_data);
      _data = "";
    }
  }
});


 

The CR+LF bytes to detect the end of the JSON document produced by the Arduino sketch, so inside the "data received" event I need to check for the presence of the CR+LF pair. If this the case, I can send data to the web client

 

As I said, the Arduin sketch uses the serial connection (which is typically wrapped by the Bridge library) to send data. In order to have full access to the serial port, we first need to change the /etc/inittab file and remove the link between the serial port itself and the console. This operation is very simple: just open the file /etc/inittab and comment the last line as shown here

 

::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
# removed to use Serial1 from Arduino sketch
#ttyATH0::askfirst:/bin/ash --login 

 

Now, in the Arduino sketch, we can initialize the serial port

 

Serial1.begin(115200)


 

and finally write any data we want. In this case, I'm sending a JSON document ready to be sent to the web client

 

Serial1.print("{\"temperature\":");
Serial1.print(hat.getTemperature());
    Serial1.print(", \"bpm\":");
    Serial1.print(hat.getBPM());
    Serial1.print(", \"pressure\":{\"min\":0,\"max\":");
Serial1.print(hat.getPressure());
    Serial1.print("}, \"pulse\":[");
    for (i = 0; i<pulseDataLen; i++)
    {
      if (i > 0)
Serial1.print(",");
      Serial1.print(pulseData[i]);
    }
Serial1.println("]}");


 

The information included in the JSON document are

  1. temperature
  2. heartbeat per minute
  3. blood pressure
  4. heartbeat samples taken by the pulse sensor. In this way, the web client can show an interesting chart with the sampled values

 

In next post, I will talk about the client-side implementation of the web interface. See you soon!

The next challenge for Matilda was a temperature gauge, she'd planned to use an LED bargraph for this but was concerned it would "light up the house like a Christmas tree". Her next thought was a servo driven slider pointing at a scale. There was not much room for this so she wondered if she needed to bother with a Fahrenheit scale. She'd ask the oldest person she knew which was Farmer Hogg. It was lunch time so she knew where to find him, in the Adam and Eve.

 

Farmer Hogg

 

Matilda arrived at the inn and soon spotted Farmer Hogg with a shepherd's pie and a tankard of ale. She showed him her notebook with the plans for the temperature gauge and asked him if he used Celsius or Fahrenheit. "I divn't bother with tweither" he retorted. "So how do you tell the temperature?" asked Matilda. Farmer Hogg looked down at his empty tankard and back up at Matilda. This was going to be a long story and Matilda hoped it would not cost her too much in beer to hear it out.

Matilda returned presently with two tankards, "Happen ah rises" started Farmer Hogg, "ah looks oot on fell an happen aal oer with white snow happen jumper n jacket, happen green with grass, " Farmer Hogg paused and took a large swig from his drink, "happen oor shirt, tupping n raddling, happen brimming yellow with lockity gowan happen vest n sheerlings" , Matilda took a swig from her own tankard to see of it might aid her comprehension. As she placed her drink back on the table Farmer Hogg tapped his empty tankard on the brim, "get yasells yan". Matilda finished her drink and got two refills from the bar. "Happen purple fell with heather" Farmer Hogg continued, "happen jacket, backend, feltle pens, snag the neeps. Happen that till be that" Farmer Hogg concluded and Matilda looked at him puzzled. Farmer Hogg looked annoyed and snatched the notebook.

 

He scribbled the following:

White Snow

Green Grass

Yellow Flowers

Purple Heather

 

Matilda thanked the farmer and staggered home, she waved the paper triumphantly at Hans before collapsing in an arm chair and falling fast asleep.

 

Matilda sees the light

 

In the morning Matilda was suffering from her "lunch" with Farmer Hogg. But she wrote up her notes from the meeting. She explained to Hans that the idea was, rather than having a complex display for the temperature they could use an RGB LED to show the temperature and status. They could use the Infineon shield, not because they needed it's power driving capability but because it could offload some of the processing. Hopefully it would also make the Arduino code simpler too.

 

ColourTemperature°C / Status
White<0 - below zero aka Ice
Purple0 - 5
Blue5 - 10
Green10 - 15
Yellow15 - 25
Orange25 - 30
Red30 +
OffOff / Sleeping
Slow FlashBooting / Getting data
Quick FlashError (Using Historic or Local Data)
Colour cycleNeeds configuring

 

 

How low can you go?

 

The Infineon shield does not implement large resistors to limit the current through the LEDs, rather it senses the current flow as a voltage over a small sense resistor and adjusts the modulation of the driving MOSFET based on that. To vary the current a reference voltage can be configured. It should also be possible to bring the average current down by increasing the off time parameter which in turn increases the LED current ripple.

LED Current Sensing LED Current Ripple

The data sheet did not provide a calculation for the current, recommending an experimental technique using an oscilloscope, it also had a big table full of examples. These values were plotted and a trend line added to produce a formula to calculate current from input parameter.

Estimate Equation

That gave a value of 3 representing 18mA or 2 representing 11mA which might be a safer starting point. The average current could then be measured with a multimeter as an oscilloscope was not available.

 

Standing on the shoulders of giants

 

Rather that starting from scratch Hans decided that he could use one of the code libraries already created during the Holiday Lights challenge which are in turn wrappers for the Infineon library. Using jancumps' review the library from ipv1 was selected.

 

The first test was to see if it was possible to drive a regular red LED with no current limiting resistor. Based on the above graph/equation, the "max current" setting was set to 1, it's lowest value (although 0 has not been tried). A multimeter was put in series with the LED to measure the current. This read a little high at 24mA so the off time parameter was incremented and successfully brought that back down to 20mA. Then a little programme was written to sweep the brightness up and down. The other thing that was tested was that the shield could be run from just 5v rather than needing a higher supply, Hans had already checked the schematic, the regulator and microcontroller on the shield were capable of running at the lower voltage. This would simplify the circuitry. The Arduino was powered from an adapter and the shield from the battery with Adafruit boost regulator.

 

Code at Github

 

Now that the system had been proven using a cheaper red LED the jumbo RGB LED could be swapped in with reduced risk of a costly burn out. The brightness was set at a mid level and code changed to cycle through the colours.

 

Code at Github

 

Whilst the circuit was being powered off it was noted that the LED stayed the same colour even once the Arduino was powered off. That could come in handy.

 

A small PCB had been considered for the LED but given that it fitted ok into the breadboard and that there are no other components than a connector, a simple stripboard will be used with some form of fastening to hold it into the wooden frame. Standoffs attached with glue have previously shown to work.

 

Reference:

http://www.lakelanddialectsociety.org/dialect_glossary.htm

http://www.element14.com/community/docs/DOC-70582

 

Next: Enchanted Objects Design Challenge - Taming the Python

This update brings you how the clock will personally greet you when you stand in front of (it?, "It" seems so impersonal. My daughter Chrystal has named it "Tic", she says since we are going to make it talk. "Tic - T(alk)". Close enough explanation I guess. I use it as an acronym ("T"alking - "I"nteractive - "C"lock ). Here is the missing bracket).

 

So we programmed the Arduino to use the 2x16 LCD screen and Ultrasonic sensor to accomplish this. Below are pictures with the readout on the screen:

DSC00290.JPG

 

 

Please excuse the crudity of my drawing, Chrystal is still laughing about it.....

height.jpg

So right now we have got the family member recognition up and running. The binary clock attachment is working. We have the thermostat controller running but we have to get the voice control connected and working. The light control hasn't been set up yet, but the programming is complete. It works similar to the height recognition system except it looks for movement and non-movement. Still working on the clock itself, once it is built the time keeping program will be the final step.

 

More explanation of the light control:

 

So the ultrasonic sensor has set distances programmed into the Arduino, like from the clock to the couch unoccupied.

Area.jpg

When someone is sitting on the couch the sensor reads a different distance which makes it aware that someone is there.

Area2.jpg

Now I have set the parameters to have a "<" and ">" value, if this value stays "=" for more then the set amount or reads the default of the couch being unoccupied the lights will dim for 2 minutes then shut off. If the couch is occupied and the occupant hasn't moved (value stays consistent for set time) it is considered they have fallen asleep. If someone walks in the room, the lights will only turn on to dim as to not wake the sleeping family member unless the couch is empty.

I will set the lights to turn on dim if it past a certain time of night unless you ask "Tic" to turn the lights on full.

 

Thank you for reading,

 

Dale and Chrystal Winhold

rpbruiser

Genie Lamp [Update]

Posted by rpbruiser May 8, 2015

So there is no real progress on my project this week unfortunately. Being a high school senior in a residential program is difficult to find the necessary  tools at appropriate times. I have talked to the engineering professors and have begun to set up times in which I will be allowed to use the labs and materials based on my schedule. However, I was able to start a 5 hour print of my enclosure for the Yun and Infineon and RGB. I won't be able to access this enclosure until Monday though. I plan on using the labs next week and finishing up the last leg of my project before I begin working on aesthetics. I just thought I would give everyone an update, and hope the rest of your projects are coming along as well too!

Hans was struggling with installing requests[security] the compile issues seemed to keep coming back like a hydra regrowing its heads.

 

To take a break he went to visit his friend Albert. Albert invited Hans in and disappeared into the kitchen to make some tea. "Make yourself at home" called Albert from the other room. Hans sat down on the sofa next to a grey cat. It looked friendly so Hans went to pet it. As soon as he moved the cat stretched out its paw and out shot the claws. Hans recoiled narrowly avoiding a serious injury. "Ah, I see you've met, Injector" said Albert as he came back in with a tray of tea and biscuits. Albert grabbed a throw from the back of the sofa and deftly wrapped the cat in it. The cat peered up at Albert and purred contently.

 

SamCat.jpg

Photo Credit: "Sam cat" by Alan Barnet

When he returned home, Hans decided to work on the python code and roughed out the following high level design.

 

Steps
Get Location
Generate URL
Check URL
Parse Response
Map Weather Codes

 

He had considered using the users IP address to identify location but as his Google search page kept sending him to Google.pl and Microsoft thought his office was in the USA he was not so sure on this approach. Rather, he decided to read the value from a file and hopefully would later have some time to change the UI to allow the user to enter the location. If the users were supplying the location he'd need to ensure his code was protected from parameter injection by correctly wrapping and encoding the provided parameters.

 

This is the resulting python code.

 

import requests, json, sys, urllib, urlparse


def get_location():
  with open('/etc/WeatherAPI.conf', 'r') as f:
  location_name = f.readline()
  f.close()
  return location_name


def build_url(location):
  url = "https://query.yahooapis.com/v1/public/yql"
  q = "select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text = '" + urllib.quote(location) + "') and u='c'"
  params = {'q': q, 'format': 'json', 'env': 'store://datatables.org/alltableswithkeys'}

  url_parts = list(urlparse.urlparse(url))
  query = dict(urlparse.parse_qsl(url_parts[4]))
  query.update(params)

  url_parts[4] = urllib.urlencode(query)

  return urlparse.urlunparse(url_parts)


def call_api(url):
  r = requests.get(url, timeout=(10, 60)) # Connection timeout and read timeout
  if r.status_code != 200:
  raise RuntimeError('API Call Failed(%s)' % r.status_code)
  return r


def map_code(code):
  # Map condition codes to expected precipitation
  # https://developer.yahoo.com/weather/documentation.html
  # 1 = very sunny, 3 = changeable, 5 = very rainy
  codes = {'0': {'n': 'tornado', 'p': '3'},
  '1': {'n': 'tropical storm', 'p': '5'},
  '2': {'n': 'hurricane', 'p': '5'},
  '3': {'n': 'severe thunderstorms', 'p': '5'},
  '4': {'n': 'thunderstorms', 'p': '5'},
  '5': {'n': 'mixed rain and snow', 'p': '5'},
  '6': {'n': 'mixed rain and sleet', 'p': '5'},
  '7': {'n': 'mixed snow and sleet', 'p': '5'},
  '8': {'n': 'freezing drizzle', 'p': '5'},
  '9': {'n': 'drizzle', 'p': '4'},
  '10': {'n': 'freezing rain', 'p': '5'},
  '11': {'n': 'showers', 'p': '4'},
  '12': {'n': 'showers', 'p': '4'},
  '13': {'n': 'snow flurries', 'p': '4'},
  '14': {'n': 'light snow showers', 'p': '4'},
  '15': {'n': 'blowing snow', 'p': '3'},
  '16': {'n': 'snow', 'p': '4'},
  '17': {'n': 'hail', 'p': '4'},
  '18': {'n': 'sleet', 'p': '4'},
  '19': {'n': 'dust', 'p': '3'},
  '20': {'n': 'foggy', 'p': '4'},
  '21': {'n': 'haze', 'p': '3'},
  '22': {'n': 'smoky', 'p': '3'},
  '23': {'n': 'blustery', 'p': '3'},
  '24': {'n': 'windy', 'p': '3'},
  '25': {'n': 'cold', 'p': '3'},
  '26': {'n': 'cloudy', 'p': '3'},
  '27': {'n': 'mostly cloudy (night)', 'p': '3'},
  '28': {'n': 'mostly cloudy (day)', 'p': '3'},
  '29': {'n': 'partly cloudy (night)', 'p': '3'},
  '30': {'n': 'partly cloudy (day)', 'p': '3'},
  '31': {'n': 'clear (night)', 'p': '1'},
  '32': {'n': 'sunny', 'p': '1'},
  '33': {'n': 'fair (night)', 'p': '2'},
  '34': {'n': 'fair (day)', 'p': '2'},
  '35': {'n': 'mixed rain and hail', 'p': '4'},
  '36': {'n': 'hot', 'p': '1'},
  '37': {'n': 'isolated thunderstorms', 'p': '4'},
  '38': {'n': 'scattered thunderstorms', 'p': '4'},
  '39': {'n': 'scattered thunderstorms', 'p': '4'},
  '40': {'n': 'scattered showers', 'p': '4'},
  '41': {'n': 'heavy snow', 'p': '5'},
  '42': {'n': 'scattered snow showers', 'p': '4'},
  '43': {'n': 'heavy snow', 'p': '5'},
  '44': {'n': 'partly cloudy', 'p': '2'},
  '45': {'n': 'thundershowers', 'p': '5'},
  '46': {'n': 'snow showers', 'p': '5'},
  '47': {'n': 'isolated thundershowers', 'p': '4'}}
  state = codes.get(code)
  if not state:
  raise RuntimeError('Unknown weather code returned')
  return state['p']


def parse_weather(json):
  text = json['query']['results']['channel']['item']['condition']['text']
  code = map_code(json['query']['results']['channel']['item']['condition']['code'])
  temp = json['query']['results']['channel']['item']['condition']['temp']
  return {'text': text, 'code': code, 'temp': float(temp)}


def main():
  try:
  loc = get_location()
  weather_url = build_url(loc)
  r = call_api(weather_url)
  j = json.loads(r.content)
  weather = parse_weather(j)

  print 'OK!,%s,%s,%4.2f' % (weather['text'], weather['code'], weather['temp'])

  return 0

  except Exception, err:
  print 'Err,%s,0,0.0' % str(err).replace(",", " ")
  return 1


if __name__ == '__main__':
  sys.exit(main())










 

For the test location of Chicago,IL the report came out as

 

OK!,Fair,2,16.00

 

Changing the URL to one with a known invalid security certificate returns the following:

 

Err,[Errno bad handshake] [('SSL routines'  'ssl3_get_server_certificate'  'certificate verify failed')],0,0.0




 

Back into Arduino

 

So the next job on the coding is on the microcontroller side to parse this string returned from the API and move the servo and light the lights accordingly. The issue with the requests[security] install will also need to be resolved some how.

 

Next: Enchanted Objects Design Challenge - Farmer Hogg and the Lockity Gowan

 

Reference

 

File reading

https://docs.python.org/2/tutorial/inputoutput.html

 

URL Encoding

http://stackoverflow.com/questions/1695183/how-to-percent-encode-url-parameters-in-python

 

URL Building

https://docs.python.org/2/library/urlparse.html

 

Validate certificates

http://docs.python-requests.org/en/latest/user/advanced/

 

Parsing the JSON

https://docs.python.org/2/library/json.html

 

Mapping via a dictionary

http://learnpythonthehardway.org/book/ex39.html

Good news, my Yun has arrived. I am not quite ready to move on to the internet side of my project, but it nice to be able to see what I am working with. On the minus side, the Ups shipping notification arrived two days after the Yun, but thankfully I was at home on the day that it arrived so there were no problems with the delivery.

IMG_20150330_092344.jpg

And now onto my progress. Having determined that the screen could be driven from 5v, my first step was to try and power it from the Uno. The minimum safe resistance on the io pins of most Arduinos is around 200 ohms, so to test the display I wired a 220 ohm resistor in series with it, and hooked it up to the Uno. My original plan to test the display was to use a serial terminal to communicate with the Arduino so I could change PWM values on the fly to work out the correct values for this display, but the code I uploaded for a test uploaded so quickly compared to the sketches on my Leonardo that I decided just to use a simple analogue write and change the value and re upload each time. This could damage the chips memory over time, but I wanted to take advantage of this new boards features the first time I used it. Using trial and error, I was able to work out display values to get the screen to work correctly. However, I had to use very low PWM values to the point that I could not get the resolution that I needed. To fix this I added a second 220 ohm resistor in series with the first and changed my PWM values accordingly to get a reasonably accurate display working. In the final design, I will use a single 470 ohm resistor, but at the time I did not feel like rummaging through my part bins for a second time. Using the new PWM values I then created a quick demo programming that moves the dial up through all the values. Some tweaking is still needed but it works reasonably well.

 

Now that I have the display working, it is time to think about my backlight. My original plan was a monochromatic backlight driven by a single PWM pin from the Arduino. However, now that I have moved away from the motor shield, I am able to very easily install the Infineon LED sheild instead. I am going to use the shield to implement a traffic light style indication of the number of posts from the backlight, starting green and moving through to yellow and red. Rather than an RGB led, I am going to use a separate red, green and yellow led. The In fine on shield does not come with headers installed, so I first had to solder these into place. It is worth bearing in mind that no headers are included with the sheild, I had to use the ones from the Arduino starter kit. Nonetheless, breaking apart and soldering on the headers was very quick and easy. I also used some spare headers to attach to create an adaptor to plug the outputs from the sheild into a breadboard, to a low the display to plug into the breadboard, and to add some wires coming off the sheild to more headers so I could still use the display as well as add some buttons. To power the sheild I just cut the end off a twelve volt power brick I had lying around.

  The first issue I had was with downloading the example code. Strangely enough, the download from the official website required running a programming to create the correct folders. As a Linux user, this could have been an issue. Thankfully though, it was able to run under WINE with no issues. My next issue was setting the current limit. I had some issues lowering the current limit from the driver through software. Instead of fighting with code I decided just to use some resistors to ensure the current passing through the LEDs was not to high. This is a bit of a dirty fix, but for a prototype it is not to much of an issue.

  Eventually I was able to modify the example code to the point where I could control the backlight. I then combined this with my previous demo programming and was able to cycle through the values on the dial and backlight. A few more modifications, and I was able to control the values with a pair of buttons. The buttons work through a variable in the code which in the final version will be updated by the number of message in my inbox. I also added the option to deactivate the backlight with a third button, which will be replaced with a switch in the final version. This is so I can have the unit in a bedroom and turn off the backlight to sleep. I have set up the light to go red quite a while before the dial reaches the end of the scale. This mostly because my inbox rarely has more than 6 messages, and I want to try and enjoy the full color spectrum available to the light system.

 

  My next step is going to be working on the code for the internet side of this project. If anyone knows a good way to create the cookies on the Yun to log in to the site so I can parse for the message count, or has another way of getting the message count please leave it in the comments.

Today I've soldered the first prototype of the key fob:

P5052642.JPG

Please forgive the very raw prototype. As 1-wire device I've used the DS2401 which provides the ID only (as opposed to my earlier test where I used an EEPROM), because it is the cheapest 1-wire device I could find. Unfortunately I was not able to get them in the SOT-223-3 package which is the smallest package I might be able to solder. Instead I went for the TO-92-3 package which is through hole and easy to solder.

On the upper side of the hanging hole you can see the copper wire I used to make sure that the PCB and the hook are in contact. I did the same for the hole for the ring, but only on the lower half. The ground wire of the DS2401 is connected to the ring hole and the 1-wire data pin (pointing up in the photo above) is connected to the hanging hole.

And that's how the finished prototype looks:

P5052643.JPG

Ever since the storm Hans and Matilda's power supply had been quite flaky. The electricity company had sent engineers round several times who found and fixed loose connectors and faulty wiring deep in the forest. But the problems kept occurring so Matilda was keen to get their battery based supply up and running.

MatildaAndBattery.jpg

 

The Blue Haired Woman

 

On the day that Matilda planned to connect up the Yun they had a knock on the door. Hans opened the door and was greeted by a large blue ball of fur, carrying a pie. "Hello Hans" said Mrs Spratt's voice from inside the ball. Hans invited her in and they went through to the kitchen where Matilda was busy soldering. A space was cleared for the pie and Hans found a knife and plates so they could all have a piece. Mrs Spratt explained that she'd found an old shampoo recipe made from blueberries that was supposed to make your hair stronger and full bodied. It was not till after she tried it out that she read that it sometimes had side effects. She'd had a few berries left over so had decided to make a pie for Hans and Matilda. Mrs Spratt had been eating whilst she was talking so Hans washed up the empty pie dish and Mrs Spratt took it home.

 

Off Grid Living

 

Matilda was keen not to have any unexpected side effects with her battery and power so she built a simple circuit on the breadboard to test it.

PowerTest.jpg

The AdaFruit board that has been selected provides 5.2v rather than 5v so the schematic was examined and each of the datasheets checked to avoid an expensive mistake.

 

ComponentData Sheet
Max Supply Voltage
ATMega3u4http://www.atmel.com/devices/atmega32u4.ATmega32U4?tab=parameters5.5v
RT8010 - 3.3v Regulator for the MIPS Processorhttp://www.richtek.com/download_ds.jsp?s=2825.5v
MAX3375E - Bridge Level Shifterhttp://www.maximintegrated.com/en/products/interface/level-translators/MAX3375E.html/tb_tab05.5v
NTB0104 - ICSP Level ShifterNTB0104UK :: NXP Semiconductors5.5v
NTB0102GF - Handshake Level ShifterNTB0102GF :: NXP Semiconductors5.5v
AU6350 - USB hub and card Readerhttp://wenku.baidu.com/view/6c347a4ac850ad02de8041905.5v

 

The voltage across the LED and resistor were measured and was around 5.1v so comfortably in the range of all of these components.

 

Mounting the Yún

 

There are several engineering drawings for the Arduino series explaining where the holes are located, it's also possible to use a board as a template to mark the holes. After looking at a selection mounting plates on Thingiverse, Matilda decided to go for 3mm threaded rods, captive nuts and some spacers.

PinsAndBoards.jpg

Ref:

 

The Arduino Yún provided it's own challenges here. The SD card is right next to the mounting hole so makes it difficult to put in a spacer. The height of the 90° USB and Network sockets are particularly high so long pins are needed. The stacking headers found from CPC did not have enough clearance so were swapped those with the long pins provided in the kit and then soldered the shortened stacking headers on top. The Infineon board could then be used with standard length pins.

CaptiveNuts.jpgTestFitting.jpg

The protoshield also threw in it's own curveball having only 3 out of the 4 standard mounting holes. With the test fitting it's fairly sturdy so one of the screw threads can be shortened to just support the Yún.

 

The battery will also need mounting somewhere, perhaps a battery box strapped to the back of the house? This is also a challenge as the pre-wired cable is quite short.

 

The Wolf

 

Meanwhile in the forest the wolf put away his wire cutters and realised he'd need to find another way to sabotage the project.

The blood pressure measurement system revealed to be more challenging than I expected...

As a matter of fact, the pulse detection algorithm takes up most of the Atmel 32U4 resources, thus leaving too few time to other tasks. This has some counter-effects, the most noticeable being a non-uniform movement of the continuous rotation servo.

I tried several workaround, like moving the pulse detection algorithm in Timer3 ISR instead of Timer1 ISR (and obviously forcing the Servo  library to use Timer1 instead of Timer3) but the problem was still there. I also tried to skip the Servo library and generate the PWM for the servo using the analogWrite function, but the problem was not resolved. I guess the problem is that the pulse detection algorithm completely disables interrupts, thus causing the PWM signal to jitter randomly

For this reason, I decided to move the servo control logic to another Arduino board. The Enchanted objects challenge's kit included a Arduino UNO board, but unfortunately I can use this board due to size contraints. So the choice was for the Arduino Mini Pro board, which is small enough to accommodate inside the MagicHat.

Despite the additional work this decision involves, there are also some benefits. For example, the mouth control logic I originally removed from the list of features I planned to implement is returning now into play.

The connection between the two boards is very simple:

  • a digital output driven by Arduino Yun tells Arduino Mini to start the blood pressure servo
  • a digital output driven by Arduino Yun tells Arduino Mini to bend the hat

 

 

11 - Boards_bb.png

Today my goal is to cut more gears and other parts of the clock to get it to the assembly stage. This clock will be one of my long desired accomplishments, woodworking is my life and passion. Anyone interested in seeing other creations I have done check out: http://www.woodandironcreations.com/ This is a totally one of a kind woodworking creation company my partner and I own.

 

I have set aside the thought of using the SAMA5D4 for now, I have focued on the arduino and YUN for my project. I am working on an OS for the SAMA, but there is no way to complete it on time, it is still going to be a project to complete later.

 

Dale Winhold

20150503.jpeg.jpeg

 

One of the enchantments for my 50's turntable is an Arduino Light Organ.

The organ uses FFT to calculate the amount of bass, middle and treble in the turntable signal.

I'm building a simple signal adapter to boost the tiny pickup coil signal.

 

Photo 03-05-15 18 37 48.jpg

 

One Transistor Amplifier

 

There are three reasons why I can't feed the pickup coil signal directly into the Arduino.

The amplitude is small, it can't drive the impedance of an analog input pin (it has to drive an audio pre-amp too).

And it's a negative signal half of the time.

 

The quality of the amplifier isn't that important - as long as it doesn't create too much additional harmonics and doesn't feed anything back into the source signal.

The most important thing for this module is that it adds a positive bias to the signal, so that the full signal is within range for the ATMega ADC.

This 5-component amplifier does the job. It has a so-so frequency response due to my choice of capacitor, and it is nowhere near linear.

If necessary, I will make firmware changes to correct for that.

 

drawing.jpeg

I've measured bandwidth and captured the scope output on 4 spots in the audio range. This is measured without the input resistor of 100 K. Input signal is 350 Vrms.

I don't think I have to expect too much on the range of this turntable (Maybe I can test that later. I have a test record).

But you see that it's a poor performer.

 

20 Hz200 Hz2 kHz20 kHz
1transistor20.jpg1transistor200.jpg1transistor2k.jpg1transistor20k.jpg

 

It may be bad on the pictures above, but when I use it for what it is intended, it is quite ok.

The signal has its necessary positive dc bias. And although I haven't tried it in practice yet, I bet it'll do the job just fine.

 

signal.jpg

 

I first breadboarded the circuit to do the measurements, but this is a fine candidate for the proto-shield that came with the Enchanted Objects package.

Photo 03-05-15 15 29 23.jpg

 

 

Table of Contents
Chapter 1: Fix the turntable
1: Perpetuum Ebner Musical 1
2: A Time to Kill and a Time to Heal
3: Preparation for Motor Drive
4: Motor control with Infineon Motor Shield and Arduino UNO
5: Turntable speed sample testbed with Arduino UNO
6: Turntable Speed Sensor design
7: Control Theory - End of Chapter 1
Chapter 2: First Enchantments
8: Digital Light Organ Enchantment
9: Autonomous Servo Lift
10: SMD Time - Solder the IR Speed Sensor PCB
11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program
12: Son et Lumiere - End of Chapter 2
Chapter 3: Taming the Board
13: Breakthrough - Run my own C++ Program on the SAMA5D4
14: Digital Light Organ Input Buffer
15: SAMA5D4 Blinky
16: Scope Creep
17: Audio Sampling with 16-bit ADC ADS8343
18: Sending Files to SAMA5D4 over USB
19: Port my Light Organ from Arduino to SAMA5D4
20: Fast Fourier Transform on the SAMA5D4 - End of Chapter 3
Epilogue: Reaching for the Clouds
21: Right-Sizing my Plans
22: My Own C++ Buffered Sampler on the SAMA5D4
Interlude
23: Building In the Motorized Light Organ
24: Up to the Clouds with Yún
25: Publish or Perish
26: Turntable Finished
Stretch & Boni
Bonus 1a: Remote Light Organ with WiFI pt. 1
Bonus 1b: Remote Light Organ with WiFI pt. 2
Grande Finale: Paho MQTT Client on the SAMA5D4
Related blog
Vintage Turntable repair: Can I fix a Perpetuum Ebner from 1958
Review 1: Atmel SMART SAMA5D4 Xplained Ultra Unboxing and First Steps
Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source
Review 3: Digital Continuous Rotation (360°) Servo Part 1
Review 4: Digital Continuous Rotation (360°) Servo Part 2
Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running
Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support
poem
Enchanted Objects: Let's work together to tame the ATMEL SMART SAMA5D4 Xplained Ultra kit
17 bis: Off South...
Review 7: Atmel SMART SAMA5D4 Xplained Ultra - C++ ADC Example on Linux
Review 8: Atmel SMART SAMA5D4 Xplained Ultra - Product Review
Review 9a: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 1
Review 9b: Atmel SMART SAMA5D4 Xplained Ultra - Set up ADC Buffer with Hardware Trigger Part 2
Review 10: Atmel SMART SAMA5D4 Xplained Ultra - New Content on AT91.com
1958 Turntable from the Black Forest - Summary of the Enchanted Player Story

I discovered this morning that back in 1945 there was a film called the "Enchanted Cottage" perhaps there will be a remake?

FilmPosterMod.jpg

Wow, half way already!!

 

Here is an in depth update at where Chrystal and I are at.

 

Clock building:

This is a slower then hught process, a lot of scroll sawing in making gears. I keep getting tempted with the CNC machine, but this I want to do by hand. Chrystal has been helping cutting out the gears as she has learned patience (from me of coarse). Below are pictures of the gears:

 

DSC00145.JPGDSC00148.JPG

 

Next we have finaly received our voice recognition module. Attached are pictures and some sample programming:

 

DSC00149.JPG

 

 

#include <SoftwareSerial.h>
#include <VoiceRecognitionV3.h>

/**       
  Connection
  Arduino    VoiceRecognitionModule
   2   ------->     TX
   3   ------->     RX
*/
VR myVR(2,3);    // 2:RX 3:TX, you can choose your favourite pins.

uint8_t records[7]; // save record
uint8_t buf[64];

int led = 13;

#define onRecord    (0)
#define offRecord   (1)


void printSignature(uint8_t *buf, int len)
{
  int i;
  for(i=0; i<len; i++){
    if(buf[i]>0x19 && buf[i]<0x7F){
      Serial.write(buf[i]);
    }
    else{
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]");
    }
  }
}

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized.
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");

  Serial.print(buf[2], DEC);
  Serial.print("\t\t");

  if(buf[0] == 0xFF){
    Serial.print("NONE");
  }
  else if(buf[0]&0x80){
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  }
  else{
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");

  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3]>0){
    printSignature(buf+4, buf[3]);
  }
  else{
    Serial.print("NONE");
  }
  Serial.println("\r\n");
}

void setup()
{
  /** initialize */
  myVR.begin(9600);
 
  Serial.begin(115200);
  Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
 
  pinMode(led, OUTPUT);
   
  if(myVR.clear() == 0){
    Serial.println("Recognizer cleared.");
  }else{
    Serial.println("Not find VoiceRecognitionModule.");
    Serial.println("Please check connection and restart Arduino.");
    while(1);
  }
 
  if(myVR.load((uint8_t)onRecord) >= 0){
    Serial.println("onRecord loaded");
  }
 
  if(myVR.load((uint8_t)offRecord) >= 0){
    Serial.println("offRecord loaded");
  }
}

void loop()
{
  int ret;
  ret = myVR.recognize(buf, 50);
  if(ret>0){
    switch(buf[1]){
      case onRecord:
        /** turn on LED */
        digitalWrite(led, HIGH);
        break;
      case offRecord:
        /** turn off LED*/
        digitalWrite(led, LOW);
        break;
      default:
        Serial.println("Record function undefined");
        break;
    }
    /** voice recognized */
    printVR(buf);
  }
}

 

We also added in a famly member recognition program. Here we are using an ultrasonic sensor which wil be integrated into the clock to sense te height of whoever is in front of the clock. The clock will communicate personally with the family member by name. At thi time I have it to light up LED's as the rcognition, my wife is set for 3 lighs, at the tme of the screen shot it was recognising myself. Below are pictures and programming:

 

DSC00157.JPG

DSC00159.JPG

void setup() {
   pinMode (2,OUTPUT);//pin 2 to vcc
   pinMode (5,OUTPUT);//pin 5 to GND
   pinMode (10, OUTPUT);
   pinMode (11, OUTPUT);
   pinMode (12, OUTPUT);
   pinMode (13, OUTPUT);
   Serial.begin(9600);
}

void loop()
{
digitalWrite(2, HIGH);

   long duration, inches, cm;


   pinMode(3, OUTPUT);// pin 3 to Trig
   digitalWrite(3, LOW);
   delayMicroseconds(2);
   digitalWrite(3, HIGH);
   delayMicroseconds(5);
   digitalWrite(3, LOW);


   pinMode (4, INPUT);//pin 4 to Echo
   duration = pulseIn(4, HIGH);

   // time into distance
   inches = microsecondsToInches(duration);

 
   Serial.println();
 
   delay(100);
  
      if (inches < 48 && inches > 38)
   {
     Serial.print("Hi Nicholas");
     digitalWrite(10, HIGH);
     delay(100);
     digitalWrite(10, LOW);
    
     delay(100);
    
   }
  
   if (inches < 38 && inches > 34)
   {
     Serial.print("Hi Chrystal");
     digitalWrite(10, HIGH);
     digitalWrite(11, HIGH);
     delay(100);
     digitalWrite(10, LOW);
     digitalWrite(11, LOW);
    
     delay(100);
    
   }
      if (inches < 34 && inches > 30)
   {
     Serial.print("Hi Mom");
     digitalWrite(10, HIGH);
     digitalWrite(11, HIGH);
     digitalWrite(12, HIGH);
     delay(100);
     digitalWrite(10, LOW);
     digitalWrite(11, LOW);
     digitalWrite(12, LOW);
    
     delay(100);
    
   }
  
  
   if (inches < 30 && inches > 25)
   {
     Serial.print("Hi Dad");
     digitalWrite(10, HIGH);
     digitalWrite(11, HIGH);
     digitalWrite(12, HIGH);
     digitalWrite(13, HIGH);
     delay(100);
     digitalWrite(10, LOW);
     digitalWrite(11, LOW);
     digitalWrite(12, LOW);
     digitalWrite(13, LOW);
    
     delay(100);
    
   }
  

We have been working with the servo to control the lights and the temperature which is coming along very well. Chrystal is creating this parts of the project, we will update more shortly.

 

Thank you for reading,

Chrystal and Dale Winhold

Package Manager

All modern Linux distributions come with a package manager such as Yum or RPM. The Linux distribution included on the Arduino Yun is no exception. It uses OPKG (Open PacKaGe manager).

To get an upto date list of package you use the command opkg update to list the package available opkg list and there's install, update and remove commands for actually managing the packages. The instructions are covered in details in the link above.

 

Configuration

You can change the behaviour of OPKG via a configuration file /etc/opkg.conf . This contains the details of where OPKG downloads the packages from and where they are installed to. It can also incorporate signing and proxy settings if you need those for your system.

 

Sources

When you install an image to the Yun it contains some default locations where the package manager can look for new packages. And most of the time that's fine. However, if you find yourself not being able to install a third party component, in my case Python's requests[security] package. Then you might want to check some other package repositories. Note that some of these locations have packages for multiple systems so for the Arduino Yún you want to look for the "generic ar71xx" branch.

 

Arduino.cc

http://downloads.arduino.cc/openwrtyun/1/packages/

OpenWRT

http://downloads.openwrt.org/

Linino

http://download.linino.org/

 

Warning!

You may find that using other sources for packages causes things to fail. This is because the image creators have been very specific in what packages they put together to ensure they all work. Mixing packages is almost guaranteed to cause you additional work. What you need to go is to unpick the chain of packages for your problem installation. Once you've done this you can remove the old packages and re-install from the new repository.


Creating Packages

If you've got a lot of components you have created to put on your Yún and want to deploy to several devices then creating your own ipk packages might be a good solution.