Skip navigation
2015

Requirement

 

Before integrating LEDs I have to revise the communication protocol since the necessary information was not present before. Furthermore some properties are missing. The protocol should be:

  • Future proof
  • Secure
  • Safe against transmission errors / modified communication

Following information was not present in the previous protocol:

  • Key status changes
  • LED status

LED status will be changeable by the client.

 

Message Protocol

 

This is the specification of the version 1 of the communication protocol. The previous (version 0) is obsolete an won't be used anymore.

For the encryption mode used (CBC), an initialization vector (IV) is needed. To successfully decrypt the IV has to be known by the clients. It is sent before the message:

<random IV><encrypted message>

Where the message is of the format shown in the table below.

 

#MSBLSB
0Magic Number
1VersionLength
2Time
3RND
:RND
6Key Status Bits
7Key Status Changed Bits
#MSBLSB
0RedGreenBlueBrightness LED 0
1RedGreenBlueBrightness LED 1
:
7RedGreenBlueBrightness LED 7

The message consists of two 128 bit blocks where the unused bytes in the first block are filled with random numbers. The block length of 128 bits resembles the block length of AES which works is independent of the key length. Therefore this choice makes sense but is not a requirement since AES does automatic padding. The second Block contains the color and brightness values for the (max) 8 LEDs. Each is represented as a 4 bit for each component (RGB) and brightens value. This should be enough accuracy since the LEDs are used for signaling and the colors should be distinguishable. More values will result in many indistinguishable colors.

The time field contains the lowest 16 bit of the JavaScritpt getTime() which is defined as the number of milliseconds between midnight of January 1, 1970.

Messages can be sent in both directions client -> server and server -> client. The server ignores everything but the RGBL data in the second block. This is used to set the color of the LEDs.

Protocol.png

Since push message is sent to every registered cloud service client the sender may also receive the message. The client or server can detect this by comparing the whole received message against the most recent sent and then silently discard the duplicate message.

Status Update Message

Status updates are sent by the server on status changes. To disguise the time of actual changes to an external observer status updates are sent in random periods. The extraneous updates can be identified by a Key Status Changed field containing only zeros. The client is expected to silently discard this message.

On server start it does not have any previous status thus it will send an status update message with set all bits of the Key Status Changed field to one. The client may report this event as server restart and must update the status to the values sent by the server.

If the client restarts it sends a message with all color values set to 0 and all brightness values to the maximum to signal the status update request. The server will answer this with a status update as described below.

Color Change Message

Color change messages are status update messages sent by the client. The server will ignore all values but the color values. Color values where the R, G and B components are all zeros are ignored. After changing the color values according to the message the server sends a status update.

When the client restarts it sends a color change message with the color values set to 0 and the brightness to the maximum. This message does not result in any colors to be changed but the status update is sent.

 

Forward Compatibility

To make to protocol future proof I have to add at least forward compatibility.

From Wikipedia:

Forward compatibility is the ability of a design to gracefully accept input intended for later versions of itself. The concept can be applied to entire systems, electrical interfaces, telecommunicationsignals, data communication protocols, file formats, and computer programming languages. A standard supports forward compatibility if older product versions can receive, read, view, play or execute the new standard gracefully, perhaps without supporting all new features.

 

To achieve this I include a 4 bit protocol version information and a 4 bit message length. The message length will be in 128 bit blocks - 1 which allows a maximum size of 256 blocks or 4 k bytes. Future client versions which expect more data should add that on the end, the current client will read (length) blocks but ignores everything after the second one. Alternatively future protocol versions can use the random padding for information since the version 1 client will ignore the content.

Otherwise the communication does not depend on a specific transport protocol, as it is implemented now it can support any messaging app with interface to tasker with minimal changes.

 

Security

 

The easiest mode of operation for a block cipher is electronic code book (ECB). But please erase that from your mind, your scratch book and everywhere else since it is not secure. For example see the following image encrypted using ECB:

Tux_ecb.jpg

(Image by Larry Ewing lewing@isc.tamu.edu, and The GIMP  )


The original Image could easily be guessed, right?

The easiest secure mode is cipher block chaining (CBC). But as always carefully select the parameters involved according to your application. Using the same key and IV on repeating messages with CBC has the same effect as above. The blocks are encrypted to the same cipher text and therefore produce a repeating pattern. Therefore a random IV has to be used. This can be sent in the clear since it is not part of the key. The time and random padding in the middle of the first block serves as additional variation in the message.

 

Error Detection

 

To detect transmission errors or packet manipulation I simply check if the magic number at the beginning of the 1st packet is correct. Since one bit error in the encrypted packet will be distributed over the whole clear text this should be enough to serve as a indication of change. The magic number is the binary representation of the ASCII letters "CR". If a packet with a different magic number is received the packet is silently discarded.

In this post I will talk about the blood pressure measurement subsystem

The main components of this subsystem are

  1. the heart beat detector
  2. a continuous rotation servo
  3. a force sensor resistor

 

The idea behind this experimental blood pressure measurement is to replace the arm cuff that is inflated by an air compressor with an elastic rubber pulled by a servo motor. When the rubber exercise a force that is exactly equal to the pressure of the blood, the blood stops flowing through the finger. At that moment, I can read the force the finger is squeezed y means of the FSR. Force can then be converted to a pressure value by applying a simple linear conversion

The following flowchart gives an overview of the whole process

 

                                                            10 - Blood pressure measurement.png

In order to make test easier, I built a frame where all the components will be placed

 

IMG_20150429_122138.jpg

Note the plastic strip that will pull the elastic rubber back when the pressure measurement process has finished

Then I put the Force Sensor Resistor in place

 

IMG_20150429_122323.jpg

 

On top of FSR, I placed the heart beat sensor. I enclosed the sensor in foam to protect the FSR (and the patient finger as well..). Then, I placed the elastic rubber

 

IMG_20150429_124919.jpg

Then I added a microswitch to detect when the finger is in place. Since Atmel 32U4 is not that monster, this makes me save a lot of computational power when there is nothing to measure...

 

IMG_20150429_125027.jpg

 

Finally, the servo that pulls the elastic rubber has been added

IMG_20150429_130219_1.jpg

 

The implementation, is easy because I just need to put some software pieces together. I already implemented the heart beat detection algorithm and the FSR reading procedures. Moving the servo is very easy thanks to the servo library included in the Arduino IDE.

I will probably need some experiments to determine the PWM that allows the best trade-off between measurement speed and accuracy.

Also, some measurements on different subjects and a reference instrument (a blood monitor system you can buy in any pharmacy) will be reuqired to determine the force-to-pressure conversion law

After that, I hope I will finally able to measure my blood pressure...

I just received an dimmable LED (LOHAS 20W LED Chip). I plan on running a few test programs, starting with the ones that Infineon provide, while I wait for my recessed can whip extension to arrive and I will start prototyping the lamp.

 

Here is a picture of the beauty:

image1.JPG

 

I have also been messing around with TinkerCAD to build a case for the Arduino Yún and Infineon RGB Shield, which is also how I will attempt to prototype multiple lampstands. I would also like to thank all who helped me on my last post!

 

dazzling_vihelmo.png

Untitled.png

20150427.jpeg

 

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

And today is the big day. Thanks to the tutorial on mikrocontroller-software.de, I was able to cross-compile and run my first binary.

 

Hooray!

 

binfilesuccess.png

 

 

Was it difficult?

 

No. Once I found the how-to guide, I greased up my German language skills. I had everything running in less than 20 minutes.

That's always how things happen. You chase your tail for a good month. Then you find that gem on the internet that walks you through the steps.

And it turned out to be not difficult at all.

Hindsight is a %*$§.

 

Step-by-Step

 

I can't explain it better than mikrocontroller-software.de. But I've made screenshots along the way, so it would be a shame not to share them.

 

Step 1: Start Eclipse for DS-5 and create a new C++ Project

Step 2: name the project, type = Executable : Empty Project, Toolchains: GCC 4.x built-in (or another one, I wasn't adventurous enough yet to try a different one then that of the how-to guide )

Next and Finish

Step 3: create the main.cpp file by right clicking on the project and adding a new C++ source file

Step 4: Enter the source lines. I stayed faithful to the example and kept the word A7 in there.

 

#include <iostream>


int main() {
  std::cout << "Hello World! Cortex A7 Atmel\r\n";
  return 0;
}





 

 

Step 5: inform the toolchain about the target platform. You do that by setting additional flags on the command lines.

The following flag needs to be added (see the original how-to to check why ARM5 needs v7):

 

-marm -march=armv7-a



 

a:

b:

 

c:

 

Step 6: build the program

 

 

Step 7: review the console output:

 

12:21:50 **** Build of configuration Debug for project HelloARMWorld ****
make all
'Building file: ../main.cpp'
'Invoking: GCC C++ Compiler 4 [arm-linux-gnueabihf]'
arm-linux-gnueabihf-g++ -O0 -g3 -Wall -c -fmessage-length=0 -marm -march=armv7-a -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
'Finished building: ../main.cpp'
' '
'Building target: HelloARMWorld'
'Invoking: GCC C++ Linker 4 [arm-linux-gnueabihf]'
arm-linux-gnueabihf-g++ -marm -march=armv7-a -o "HelloARMWorld"  ./main.o
'Finished building target: HelloARMWorld'
' '


12:21:54 Build Finished (took 3s.862ms)



 

Step 8: load the program and set it as executable

 

a: load the program, in binary mode, with your favorite SCP tool (I use WinSCP)

 

b: start your favorite terminal (I use PuTTY) and set the executable flag and verify that all is ok

 

chmod +x HelloARMWorld
ls -l



 

Step 9: execute the program, sit back and enjoy your success

 

./HelloARMWorld



 

 

 

A big thank you to http://www.mikrocontroller-software.de/

 

 

 

Summary

 

 

Is this what I wanted to do? No, not 100%. But very very close.

My goal was to be able to build bare-metal application for the board , load and execute it.

I'm currently able to build an application, and run it on Linux.

That is a good situation to be in. It unlocks a multitude of possibilities that I wasn't able to investigate earlier.

If time allows, I will step deeper into the bare metal. But now I'm first going to enjoy my newly gained access to those new possibilities.

 

 

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

Currently...

 

Whilst Hans was busy coding, Matilda was looking into power requirements. She was worried that the batteries might take a long time to deliver so wanted to order them long before they would be needed.

 

DevicePower Required
Arduino Yun300mA
MicroSD Card100mA
Infineon RGB LED controller9mA
Servo100mA
RGB LED 20mA per colour60mA

 

Totting up the numbers she arrived at 569mA peak consumption, she realised that by turning things off and running tasks in series that number could be reduced. She also concluded that if they only checked the weather a few times an hour then their overall consumption could be reduced too.

Power.png

 

Based on these numbers she concluded that a 2000mAh battery would give them several days run time. She would need to measure the actual consumption once the circuits were assembled.

Given the small size of the cottage, a Lithium Polymer battery gave the best size to capacity, it was also easily capable of providing the peak power requirements. The PowerBoost 500 from Adafruit was selected to charge the battery and also boost the 3.7v of the battery up to 5v needed by the Yun.

 

The Flaming Postman

The next morning Matilda was telling the postman about her purchase and he explained that they could not deliver her battery. They'd stopped taking LiPo batteries after that time when old Bob's hair caught fire after a battery exploded in his sack. He was half way to the next village before someone caught up with him and helped put out the fire. "I smelt something but thought it was that pudding lane pie shop" he had said.

 

The blind man and a trip to the market

Matilda would need to collect the battery herself so grabbed her basket and headed off to the market. On the way to the market she met and old blind man carrying a basket of apples. She walked with him for sometime and chatted about the work on the cottage. As they approached the market some small boys ran up and each took apples from the man's basket, the old blind man appeared not to notice so Matilda shouted at the boys. Matilda apologised to the old blind man that she could not stop them. "I used to wave my stick at them" explained the old blind man "but that was very tiring, so now I just wear this blindfold so I don't have to watch them taking my apples". "So you're not actually blind then?" asked Matilda. "Oh, no dear", said the old man with a blindfold. Matilda said farewell and popped into the supply office to collect her battery.

PowerSchematics.png

When Matilda returned from the market with the battery she found Hans still struggling to get the appropriate modules to compile for secure python requests. "Can you believe that everyone just recommends turning off the warning messages" exclaimed Hans. Yes, Matilda could.

 

Next: Enchanted Objects Design Challenge - The Blue Haired Woman and Off Grid Living

I recognized that I tend to post only positive results but at the same time I learn a lot from the mistakes of others I decided to devote this blog to my time wasting effort of interfacing 1-Wire components from node.js. Several evenings I read blog post, documentation and code just to find out what I am doing wrong - with no result. It still did not work. Owfs was not able to detect the devices nor could the linux kernel show me the information in the /sys/bus/w1/ directory. I was a bit frustrating. I was about to order new components because I thought my first experience in SMD soldering went wrong. Today I went home a little early and spent the afternoon in my lab - despite the good weather. I used a logic sniffer to see what's going on. And this journey will be recorded in this blog post.

Setup

 

To eliminate as many unknowns from the equation I decided to test using my BeagleBone Black which I am more used to than the SAMA5D4.

P4242641.JPG

On the BBB the P9-19 and 20 are the I2C-1 which I am going to use. The DS2482-100's SDA and SCL are 3.3 V capable so they can be connected directly. The Linux configuration does not have to be changed since the I2C-1 is enabled by default. Connect the DS24B33 EEPROM and I am done! Right? First test it with i2cdetect:

i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --








The i2c to 1-wire bridge should show up at address 0x18.

NO! It isn't that easy. Reading more documentation I got a few things to try: pull-up resistors for SDA and SCL, kernel modules to load and much more. And nothing helped. So I disconnected everything and connected it again but out of frustration I did not disconnect the BBB contrary to a omnipresent warning that you never should connect anything to the pin headers while the board is running. And this time i2cdetect showed:

i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --








Vola! At least the DS2482 was detected.

If the drivers were loaded correctly /sys/bus/w1/ would show something:

root@beaglebone:~# ls /sys/bus/w1/devices/
root@beaglebone:~#








Nothing!

Maybe the drivers are not loaded? Let's check:

root@beaglebone:~# lsmod
Module                  Size  Used by
g_multi                50407  2
libcomposite           15028  1 g_multi
mt7601Usta            641118  0
root@beaglebone:~#







To install them manually I tried:

root@beaglebone:~# modprobe ds1wm
root@beaglebone:~# modprobe ds2482
root@beaglebone:~# modprobe omap_hdq
root@beaglebone:~# modprobe w1_ds2433







Nothing changed. More frustration. Ok. Don't give up! What else can I try? Other software? Other hardware? Analyse what's going on on the bus?

I decided to do the later.

 

Logic Analyser

 

Fortunately I've bought a simple USB 8-channel logic analyzer a while ago. Never used it seriously, though. Looks like is time again to learn something new. I have taped the SDA and SDL pins to see if the DS2482 works correctly. I already could verify that it is listening on address 0x18.

1-reset.png

The first action on the bus is not a surprise - we see a write to address 0x18 (the address of the bus master) and then the byte 0xF0 which is the command "Device Reset". Good.

2-read.png

I had not expected to see the read from address 0x18, but reading the data sheet I found the recommendation to read the status register to verify if the reset was performed. After reset the read pointer points to the status register, therefore a simple read will result in the value of the status register. Here it is 0x18 or in binary 0b00011000. The status register bits are DIR-TSB-SBR-RST-LL-SD-PPD-1WB where:

Bit NameDescripiton
DIRBranch Direction Taken
TSBTriplet Second Bit
SBRSingle Bit Result
RSTDevice Reset: Reset has been performed.
LLLogic Level: Reads the logic state of the 1-Wire bus without initialising a communication. Updated on every read
SDShort Detected: Updated on every 1-Wire command.
PPDPresence Pulse Detect: Set when a presence detect pulse is seen by the bus master. Updated on every reset.
1WB1-Wire Busy: reports if the bus is currently in use.

The three most significant bits are for data transfer on the 1-wire bus, the others are real status bits. In this case the RST and LL are set which means the reset was performed and the 1-Wire bus is in "high" state.

3-status-register.png

Then the next command is written to the I2C bus: 0xE1 (Set Read Pointer) 0xF0 (Status Register). So the next command has to be a read. It resulted in 0x18, the same as above.

4-1-wire-reset.png

This time 0xB4 is written to the DS2482. This is the command for 1-Wire reset.

5-busy.png

The status register is read again, but this time the result is 0x19 so the least significant bit has changed to "high" which means the 1-Wire bus is busy. The host has to wait until the command has finished. The next read returned 0x18, again. The reset was completed but no presence pulse detected. That's why I could not access any 1-Wire devices. But why? I checked the whole circuit and found two really stupid mistakes: on the 1 wire eeprom (DS24B33) the ground pin was connected to the 3V3 pin and the pull-up resistor's bands had the colours red-red-brown which is 220 Ω. The data sheet says Rpullup should be between 0.3 and 2.2 kΩ. I looked for a red-red-red labelled resistor and installed it instead. This time I got this result:

6-presence.png

Finally there is the Presence Detect Pulse!  The rest of the communication read the 1-Wire ID form the DS24B33. Now the key identification works.

 

Conclusion

 

I used a quite advanced tool to find a set of very stupid mistakes which a more experienced person would have detected on the first sight or would not have made at all.

But on the Pro side I learned how to use a quite handy tool and a lot about I2C and 1-Wire bus. Since the competition is about learning this goal was meat. For the other goals I really have to catch up now.

rpbruiser

Genie Update

Posted by rpbruiser Apr 25, 2015

Unfortunately I have gotten stuck on my project and stuffed the genie back in his lamp for a short while. I am currently working with the Infineon RGB Shield and have run into multiple issues. I am trying to run a single 5mm Red LED with it. I realize that the bulb needs to be rated for 300mA, thats why I am using resistors to allow for the 20mA LED not to burn out. I am driving it with a 9V battery, yet I realize that the rating is for 12V-48V, and this may be my issue. I am running into some mysterious magic, and I am beginning to believe that my genie has placed a curse on me. I am reading 4V-4.5V output and across the resistor, but 8V across the LED, along with the fact it will not light up unless I touch the leads of my multimeter while trying to measure the resistance, AND apparently there is no current throughout the circuit. I have bought a 300mA rated LED and am waiting on my low impact CFL to arrive, but I was trying to run test codes with a simple LED for an update. Unfortunately this has been a larger obstacle than presumed originally. But luckily I am a persistent competitor and will not let this unfortunate setback stop me from finishing this amazing opportunity.

20150425.jpeg

 

 

We're halfway through the story. It's time to close chapter 2.

 

Photo 19-04-15 19 53 22.jpg

 

Sound and Light

 

In chapter 1 I turned a broken vintage turntable into a working one. The defect AC motor was thrown out and replaced by a microcontroller driven one.
This turns the table into an autonomous device that knows how fast it should pin. It adapts its behavior to that knowledge.

That is a tactical change - from defect to working.

But a first enchantment is achieved. The table still looks the same as the day it was built, but under the hood - invisible to the eye - it has a brain ...

 

And in this chapter, the table became visible enchanted.

I added a speed indicator. This 3-LED mini-module listens to the speed regulator and shows what it's doing. Read chapter 3 for the higher power plans with this module and the Infineon RGB shield.

 

speedmonitor.jpg

 

Next was the light organ. This is fully implemented in firmware. It uses Fast Fourier Transform to analyze bass, middle and treble parts of the signal.

It's also an autonomous module

At this moment, the organ drives three LEDs - and that is going to stay like that, but once more: read chapter 3 for the higher power plans with this module and the Infineon RGB shield.

 

soundorgan.jpg

 

Servo Enchantment

 

I added a mechanical arm to the organ.

 

Photo 25-04-15 09 52 23.jpg

 

The arm has a sole (autonomous ) responsibility to hide the light organ inside the belly of the table. The light organ asks the motor to pop op when it feels like animating the scene.

That's how the whole enchanting set-up is done. All options can be removed or plugged in as desired. The whim of the day can have an impact on the table.

 

servoarm.jpg

 

And as a preparation for the next chapter, I've started to make some more space under the turntable.

I'll have to check if this impacts the strength of the case. First tests are promising.

 

 

 

BeforeAfter
Photo 25-04-15 10 19 03.jpgPhoto 25-04-15 10 21 52.jpg

 

 

side story: why do you see photos from another turntable in this post?

 

Because I fixed that this month.

 

Photo 25-04-15 09 55 13.jpg

A lady asked my wife if I could fix her 1964 Philips console. It's a tube radio and amplifier with an automatic changer turntable.

The radio worked but the turntable was defect. A good working (but newer,  lower in the food chain) changer from 1970 had to offer its life to fix the console.

That's how it goes in enchanted stories. They are often hard and violent. The life of looser isn't worth much in the fairy-tale world if it's not Walt Disney who writes the script.

 

 

(in total 20 minutes of video. Still well below peteroakes' average )

 

 

 

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

enchant.PNGThe Enchanted Objects Challenge is running from March 16th to June 26th 2015

 

 

NameSuper Enchanted Blog Time
Andy Clark

Enchanted Objects Design Challenge - Disaster strikes the Enchanted Cottage

A big thanks from Hans, Matilda and myself

Enchanted Objects Design Challenge - Remodelling the Enchanted Cottage

Useful videos and references

Enchanted Objects Design Challenge - Matilda is not happy

Enchanted Objects Design Challenge - The Woodcutter and the Blacksmith

Yun has arrived

Enchanted Cottage CAD models

Enchanted Objects Design Challenge - Back on the straight and narrow

Servo and mechanics in action

Enchanted Objects Design Challenge - Yum Yum Yun at the Enchanted Cottage

Enchanted Objects Design Challenge - Channels and a special delivery to the Enchanted Cottage

Enchanted Objects Design Challenge - The snake, the troll and the fighting dwarves

Setting up a Python Development Environment

Listening to weather on the radio

Jan Cumps

1958 Turntable from the Black Forest - 1: Perpetuum Ebner Musical 1

1958 Turntable from the Black Forest - 2: A Time to Kill and a Time to Heal

1958 Turntable from the Black Forest - 3: Preparation for Motor Drive

Review 1: Atmel SMART SAMA5D4 Xplained Ultra - Unboxing and First Steps

1958 Turntable from the Black Forest - 4: Motor control with Infineon Motor Shield and Arduino UNO

1958 Turntable from the Black Forest - 5: Turntable speed sample testbed with Arduino UNO

1958 Turntable from the Black Forest - 6: Turntable Speed Sensor design

1958 Turntable from the Black Forest - 7: Control Theory - End of Chapter 1

Review 2: Atmel SMART SAMA5D4 Xplained Ultra - Building the Libraries from Source

1958 Turntable from the Black Forest - 8: Digital Light Organ Enchantment

Review 3: Digital Continuous Rotation (360°) Servo Part 1

Review 4: Digital Continuous Rotation (360°) Servo Part 2

1958 Turntable from the Black Forest - 9: Autonomous Servo Lift

Review 5: Atmel SMART SAMA5D4 Xplained Ultra - TCP/IP running

Review 6: Atmel SMART SAMA5D4 Xplained Ultra - LINUX Distro with SSH support

1958 Turntable from the Black Forest - 10: SMD Time - Solder the IR Speed Sensor PCB

1958 Turntable from the Black Forest - 11: Yelp - who can Help me to Compile and Run my First SAMA5D4 C Program

poem

Samuel Doye

Multimeter inbox 1: The idea

Multimeter Inbox 2: First Experiments

Parker Ellwanger

The Magic Lamp

Wish One Was Granted

The Genie Gives A Tour Of His House

As The Sunsets...

Ambrogio Galbusera

MagicHat - 01 - Introduction

MagicHat - 2 - Temperature sensor

MagicHat - 3 - Accelerometer

MagicHat - 4 - Heart beat sensor

MagicHat - 5 - Blood pressure sensor

MagicHat - 6 - Heart beat detection

MagicHat - 7 - Force Sensing Resistor

MagicHat - 8 - Arduino Yun

MagicHat - 9 - Building the hat

Tanausu Hernandez

Enchanted Typewriter - Inspiration

Enchanted Typewriter - Planning

Christian Lorenzoni

No Updates

Rob Nagy

A place in the cloud Post #1 - Overview and what I did over Easter.

SAMA5D4 and my Ubuntu experience. Blog Post #2 - A place in the cloud

Manolis Nikiforakis

[ExM] #01 Espresso ex Machina introduction

[ExM] #2 First attempt on the Atmel SAMA5D4, installing JAVA

[ExM] #3 First attempt on Arduino Yun

[ExM] #4 First attempt with infineon RGB LED Lighting Shield XMC1202

Peter OakesEnchanted Mirror - Proof of concept and intro
Ayan Pahwa

My Wardrobe Enchants

The kits are here, Its Time to start

Parth PandyaEnchanted Windows - Introduction
Christoph Rieder

Smart Key Hooks - Prelude

Fairy Dust has arrived!

About Security

Smart Key Hooks – The Design

Happy Easter!

Identifying Keys

Smart Key Hooks Client

Arjuna SrimalNo Updates
Dale Winhold

Enchanted Objects - Enchanted Clock (Introduction)

Enchanted Objects - Enchanted Clock (Post #1)

Enchanted Objects - Enchanted Clock #2

Enchanted Objects - Enchanted Clock (#3)

When I was younger my Dad used to listen to the shipping forecast on the radio so he could plan his fishing and sailing trips. Given the limited vocabulary it should be possible to use a speech to text processor to convert this to a digital form. But there's also some other systems out there, that should be a bit easier.

 

If you are in the USA there is the National Weather Radio Specific Area Message Encoding.

NWR SAME provides in a digital form at specific, timely information on the nature and location of a threat to the safety of those most immediately at risk from severe weather or other hazards. Its greatest value is to significantly improve the automatic selection and distribution of messages about events that threaten people and/or property.

 

NOAA Weather Radio - Using NWR SAME

 

In Europe there seems to be a similar setup using the DCF77 Time Radio, the "reserved" bits in the signal below are reported to incorporate weather information

 

dcf77coding.png

 

DCF77 - Wikipedia, the free encyclopedia

Meteotime.com - Home

 

I've not seen anyone who's managed to read the weather off either of these systems so I'll unlikely be adding radio as a backup system if my internet goes down but it's interesting to know that these services are there.

 

Hey I'm British, I'm allowed to be obsessed by the weather!

Jan Cumps

poem

Posted by Jan Cumps Top Member Apr 22, 2015

 

 

 

 

take the quick start guide

follow the hyperlink

download Studio as advised on the landing page

experience that it doesn't support the microcontroller

skip 10 days of reading, browsing, trying

know that the board has a great controller and great peripherals

dream of the things you can make

look at the past roadtest

experience that I can't find anyone who was able to create a remarkable project

experience that people made remarkable things with smaller processors

think about all the remarks from participants of that roadtest

think about their common theme

post your questions and difficulties with the board

read comment from expert

I don't understand why people are struggling with the board

search the internet for successful projects with the board again

some are successful to load  an existing image

some are successful to build and load a linux build

some succeed to get a linux prompt

smile when you manage to get an SSH connection

question your skills

some can run a precompiled demo on predefined hardware

some got a bit further with the help of staff

wonder what the verdict will be at the end of this story

question your skills

In this post, I will talk about the building of the hat.

To build the hat, I first created a model with a thick sheet of paper. This is easier to cut and to work with. I cut the thick paper with common scissors until I got the desired shape.

09 - MagicHat parts.jpg

09 - MagicHat mockup 2.jpg

 

With this model, I proceeded to cut the PVC film the MagicHat will be made of. The PVC film is a good compromise between the flexibility required to make the hat look "human"

 

09 - MagicHat parts to cut.jpg

 

Finally I placed a baseball cap inside the hat to make it more comfortable to wear

 

09 - MagicHat with baseball cap.jpg

 

09 - MagicHat in plastic.jpg

Since realising that I could do some of the hard work for interpreting the weather APIs in Python I thought I'd check out my options for IDEs. I've been brought up for the last 20 years on Microsoft Visual Studio so I am used to having a featured IDE with projects, source control integration, debugger and intelli-sense.

 

I also did not want to work with copying files to the SD card manually.

 

I found PyCharm by the people who do Resharper that I use at work. There was a community edition which was a free license and seemed ideal for this project. The IDE also supports plugins for SCP (to sync the files to the Yun) and GitHub (my selected source control)

PythonIDE.png

I used a simple script to find the version of Python installed

Import sys
print (sys.version)



 

2.7.3 (default, Sep 14 2014, 18:44:39)
[GCC 4.6.3 20120201 (prerelease)]



 

So I ensured that I also had Python 2.7 installed locally.

 

The GitHub functionality is already installed, when I opened up the project it detected that it was using Git. Because I was using the simple GitHub UI the Git.exe was not installed so I downloaded that and installed to the default folder and pointed PyCharm at that directory. The UI guided me through a commit, merge and push to get my code changes synced up as I'd made changes to the same file on two different machines.

 

To sync files using SCP a plugin is needed.

SourceSync.png

This also needs to be configured with the IP address of the Yun which I've made sticky via my router.

 

I did not have much to debug but the debugger seemed fairly straightforward, running code without debugging is also straight forward.

 

There seemed to be quite a lot on the menus so I've removed some of the plugins that I don't think I'll be using.

 

It seems to be a good platform to work with and a low learning curve. I'll keep you updated if I find any problems with the workflow or use of the tool.

20150421.jpeg

 

 

Request for Help to Load and Run one of the sama5d4x_xplained_softpack examples

 

Success: compiling the libraries from sama5d4x_xplained_softpack

 

I have installend a GNU Cross Compilation toolset on Windows 8.x. And I can successfully compile the libraries of sama5d4x_xplained_softpack_1.2_for_CodeSourcery_201410.

I build them from the make files, and I have the compiled debug and release versions of each library in the lib folder.

 

eclipse.jpg

 

Fail: compiling the examples from sama5d4x_xplained_softpack

 

Once I go one step further and try to compile the examples, I get into errors. 132 of them.

Here's the start and end section of my log. The whole output is attached to the blog

 

16:43:44 **** Build of configuration Default for project Z_examples getting-started ****
make all
arm-none-eabi-gcc -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Werror-implicit-function-declaration -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs  -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code -Dprintf=iprintf -mcpu=cortex-a5 -ffunction-sections -g  -I../../../../libraries/libchip_sama5d4x -I../../../../libraries/libboard_sama5d4x-Xplained -I../../../../libraries -Dsama5d4x -DTRACE_LEVEL=4 -Dsram -c -o obj/sram_main.o ../../main.c
../../main.c: In function 'TC0_IrqHandler':
../../main.c:294:23: warning: variable 'dummy' set but not used [-Wunused-but-set-variable]
     volatile uint32_t dummy;
                       ^
arm-none-eabi-gcc -L../../../../libraries/libchip_sama5d4x/lib -L../../../../libraries/libboard_sama5d4x-Xplained/lib -L=/lib -L=/../lib/gcc/arm-none-eabi/4.4.1 -mcpu=cortex-a5 -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=entry -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--print-gc-sections -Wl,--stats -T"../../../../libraries/libboard_sama5d4x-Xplained/resources/gcc/sama5d4x/sram.ld" -Wl,-Map,bin/getting-started-sram.map -o bin/getting-started-sram.elf obj/sram_main.o -Wl,--start-group -lgcc -lc -lchip_sama5d4x_gcc_rel -lboard_sama5d4x_Xplained_gcc_rel -Wl,--end-group
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.data' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-ar/thumb/crtbegin.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-ar/thumb/crt0.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.ARM.exidx' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-ar/thumb/crt0.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.ARM.attributes' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-ar/thumb/crt0.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text.exit' in file 'c:\program files (x86)\gnu tools arm embedded\4.9 2015q1\bin\../arm-none-eabi/lib\libc.a(lib_a-exit.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.debug_frame' in file 'c:\program files (x86)\gnu tools arm embedded\4.9 2015q1\bin\../arm-none-eabi/lib\libc.a(lib_a-exit.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.ARM.attributes' in file 'c:\program files (x86)\gnu tools arm embedded\4.9 2015q1\bin\../arm-none-eabi/lib\libc.a(lib_a-exit.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text._iprintf_r' in file 'c:\program files (x86)\gnu tools arm embedded\4.9 2015q1\bin\../arm-none-eabi/lib\libc.a(lib_a-iprintf.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text.__sprint_r' in file 'c:\program files (x86)\gnu tools arm embedded\4.9 2015q1\bin\../arm-none-eabi/lib\libc.a(lib_a-vfiprintf.o)'

...


c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text.PIO_DisableWriteProtect' in file '../../../../libraries/libchip_sama5d4x/lib\libchip_sama5d4x_gcc_rel.a(pio.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text.PIO_GetWriteProtectViolationInfo' in file '../../../../libraries/libchip_sama5d4x/lib\libchip_sama5d4x_gcc_rel.a(pio.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.text.PIO_Output_Low' in file '../../../../libraries/libchip_sama5d4x/lib\libchip_sama5d4x_gcc_rel.a(pio.o)'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.eh_frame' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-ar/thumb/crtend.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.jcr' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-ar/thumb/crtend.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: Removing unused section '.ARM.attributes' in file 'c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-ar/thumb/crtend.o'
c:/program files (x86)/gnu tools arm embedded/4.9 2015q1/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: total time in link: 0.062000
arm-none-eabi-nm bin/getting-started-ddram.elf >bin/getting-started-ddram.elf.txt
arm-none-eabi-objcopy -O binary bin/getting-started-ddram.elf bin/getting-started-ddram.bin
arm-none-eabi-size obj/ddram_main.o bin/getting-started-ddram.elf
   text   data    bss    dec    hex filename
   1520      2      4   1526    5f6 obj/ddram_main.o
  31412      0  22428  53840   d250 bin/getting-started-ddram.elf


16:43:49 Build Finished (took 4s.303ms)




 

That's where I am at the moment. Something tells me I'm close. But then again, maybe not .

It would be great if you could give me a nod in the right direction.

 

My intermediate goal is to be able to run a headless C program on the board, with or without linux. I'm happy if I can say "hello, world!".

 

 

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

Smart Key Hooks Client

Posted by crjeder Apr 20, 2015

I started my "career" in electronics not long ago when the first Raspberry PI became available. But looking on the specs I decided that the BeagleBone Black suits my needs better and bought one. What I liked most about it after playing with it for a while was the c9 IDE and node.js. Therefore I decided to do the programming for this challenge in node.js, too.


The Cloud


As the cloud service I have chosen Pushbullet because it has:

  1. an easy, restfull API
  2. clients for all OSes
  3. integration in Tasker

Downside is: It does not offer end to end encryption. Therefore I had to Implement it. Since I do not have a lot of clients pre-shared key works well and is used in the implementation. The Pushbullet API is abstracted in a node.js module for even more convenience.

Provisional Client

The client consists of two parts, Tasker and a javascript code. Tasker is "Total Automation for Android" (Tasker website) a tool I use to automate many task on my Android devices. It is much like IFTTT but on the device not in the cloud. For security and privacy reasons "on device" is the preferred solution. What can Tasker do? Again citing from the website:

Tasker is an application for Android which performs tasks (sets of actions) based on contexts(application, time, date, location, event, gesture) in user-defined profiles or in clickable or timer home screen widgets.

With the Pushbullet integration every message received by the Pushbullet client a Tasker event is triggered. This can be used to start a task like launch a specific app or play a ring tone. Unfortunately the message content can not be accessed from the event. This would be necessary to start different tasks on different status changes of keys. To the rescue one of the available tasks is "code" which can run javascript programs. Let us step through the relevant portions of the javascript (nodejs):


var aes = require('crypto-js/aes');
var PushBullet = require('pushbullet');
var pusher = new PushBullet('xxxx'); //replace this with your token








this code snippet imports aes encryption from crypto-js and the nodejs libraray for Pushbullet. The last line instances and initializes the Pushbullet API. The returned object ('pusher') can be used to talk to the cloud. To initialize you need an application token which you can find in your account settings. This is a very weak authentication Pushbullet supports OAuth, too but I haven't tried it yet.


var options = {limit: 100};







 

For the Pushbullet API we must set a limit to the maximal returned pushes to prevent memory overruns etc.

Then call the search for the last message using the history function:

 

pusher.history(options, function(error, response)
{
    if(error) throw error;
    if(response.pushes.length <= 0) throw 'Error: no pushes';

    var i = 0;
    do
    {
        if (response.pushes[i].active && (response.pushes[i].sender_name == 'IoT-test' || response.pushes[i].receiver_email == '@ljkawsfowe') && response.pushes[i].type == 'note')
        {
            //var message = 'U2FsdGVkX1+Zls89vOpjlkXCcUQhDQrBEzZoH+3iuhU=';
            var message = response.pushes[i].body;
            if (message)
            {
                var decrypted = aes.decrypt(message, "geheim");
                var mask = 1;
                // works for Max_KEYS < 16
                for (var i = 0; i < MAX_KEYS; i++)
                {
                   setGlobal("Key" + i, ((decrypted.words[0] & mask) != 0)?"true":"false");
                   mask = mask << 1;
                }
          
                pusher.deletePush(response.pushes[i].iden);


            }
            break;
        }
        else
            i++;
    } while (i < options.limit);

    // ToDo: Error: no push found
});







 

Line 3 & 4 are for error handling. Then setup the loop for searching the response for through the past messages for one from the controller. I have set up a 'channel' for this purpose. In pushbullet channels are private by default. That's good! Depending on the interface used to send the push the sender_name or receiver_email are set. I was not able to figure out if this is a bug or if there are other differences I am not able to see. In response.pushes[i].body there should be a base 64 encoded AES encrypted message of one block. In line 15 the 'decrypted' object contains the block in 16 bit integers. The for loop in lines 18 - 22 converts the one bit status into individual Boolean variables. In line 20 a tasker API function is used to set android environment variables. The (decrypted.words[0] & mask) != 0)?"true":"false" makes use of the 'conditional operator' which is defined as:

 

variablename = (condition) ? value1:value2 
variablename = value1 // if condition = true
variablename = value2 // if condition = false


Therefore the statement in the client code could have been written as:


bitvalue = decrypted.words[0] & mask;
if (bitvalue > 0)
     bit_bool = 'true';
else
     bit_bool = 'false';


Which is more readable, by far, but obiously less compact.

So if the decrypted message starting whith 00000101b the code inside the for loop (line 18 - 22) sets the following global variables:


Key1 = 'true';
Key2 = 'false';
Key3 = 'true';
Key4 = 'false';
Key5 = 'false';
Key6 = 'false';
Key7 = 'false';
Key8 = 'false';


This values can then be used by other Tasker actions.


Line 24 deletes the message as it is processed now.


The provisional Client lacks some functions I've proposed and testing. But I'd like to share it because the development takes me to long to and I do also value your comments which have been always very useful in the past.

After their successes with the mechanics and Arduino Yun, Hans and Matilda decided to celebrate with a trip to the local inn, the "Adam and Eve". They walked up to the bar and was greeted by the bartender. Whilst they were being served they noticed a large snake behind the bar.

adameve1.jpgadameve2.jpg

Photos thanks to Will Russell

Suddenly the door burst open and a large troll charged in and marched up to the bar. He started shouting in a language which Hans and Matilda did not recognise. The snake lifted it's head and proceeded to slide along the back of the bar until it reached a dusty looking bottle. The snake flicked its tongue. The bartender picked up the bottle and poured a generous measure into a glass and passed it to the troll. The troll slapped some gold coins on the bar and marched over to a full table of people who quickly vacated to give the troll a seat.

 

From over the other side of the bar Hans and Matilda heard some raised voices. A group of dwarves were having some drinks with a tall dark haired lady. A dwarf with glasses seemed to be angry with one of the others who he claimed was not doing his fair share of the mining. The argument quickly deteriorated into a fight and the accused dwarf picked up a bottle and raised it above his head. Before he could bring down his arm it was wrapped in the coils of the snake. Hans and Matilda watched in amazement as the two fighting dwarves disappeared into endless coils of snake. It was at this point they realised exactly how big the snake was. The snake and dwarf coils headed outside, shortly after only the snake returned.

 

After finishing their drinks, Hans and Matilda thanked the bartender and asked about the snake. He told them he had bought it from a Burmese traveller when it was only a foot long. He had initially fed it on rats caught in the cellar, now he just leaves it to roam the forest at night. Hans and Matilda walked home much more quickly than usual that evening.

 

The next morning Hans was working on the Arduino Yun, he realised that both the parsing of the weather data and also security checks could be handled in Python on the OpenWRT side of the Yun.

 

Hans thought that the Python script could return a simple string representing the weather, either success or an error with precipitation and temperature as additional parameters.

 

Message formats:
OK!,Cloudy,4,12.5
ERR,Timeout,0,0.0

 

He also confirmed that python already installed on the Yun.

PythonHello.png

Hans looked at the different options for reading an API and the requests library looks to be a good solution. It was straight forward to install this on the development machine.

 

pip install requests



 

To install it onto the Yun required a little more effort as PIP is not installed.

 

opkg update
opkg install distribute
opkg install python-openssl
easy_install pip



When Hans tried to install this, the Yun ran out of space. "No space left on device". So he followed the instructions for mounting the file system onto an SD card. http://www.arduino.cc/en/Tutorial/ExpandingYunDiskSpace. After making space for the tools used to expand the disks he succeeded expanding the disks and returned to installing pip.

 

To prove his concept would work he created a simple demo.

import requests, json
print 'Getting Weather'
weather_url = "https://query.yahooapis.com/v1/public/yql?q=select%20item.condition.text%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Chicago%20IL%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
r = requests.get(weather_url)
print r.status_code
j = json.loads(r.content)
print j['query']['results']['channel']['item']['condition']['text']


 

Not a perfect result but definitely a few steps in the right direction.

root@EnchantedCottage:/mnt/sda1/Python# python GetWeather.py
Getting Weather
/usr/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:79: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
200
Rain
root@EnchantedCottage:/mnt/sda1/Python#

 

Now it was just a case of dealing with the InsecurePlatformWarning, handling timeouts and network errors, parsing the JSON and passing in the correct location code.

 

Python Reference

Exception handling
http://doughellmann.com/2009/06/19/python-exception-handling-techniques.html

Make call using requests.get
http://isbullsh.it/2012/06/Rest-api-in-python/

Certificates
https://www.python.org/dev/peps/pep-0476/#trust-database

https://pypi.python.org/pypi/backports.ssl_match_hostname/

http://stackoverflow.com/questions/1087227/validate-ssl-certificates-with-python

Also timeouts etc here
http://docs.python-requests.org/en/latest/user/advanced/

 

Next: Enchanted Objects Design Challenge - The flaming postman, the blind man and a trip to the market

Purchased an RGB led strip some time ago, 1m, waterproof, for 3€ from ebay. (Unfortunately, it was not tri-led, so keep that inmind when you purchase)

Did a quick test with a multimeter, it pulls around 170ma per channel.

The  RGB LED Lighting Shield with XMC1202 is very straight forward. Just need to solder 4 pins (SCL, SDA, GND, IC2 pull up) so you can stack it ontop of arduino uno.

DSC_0004.JPG

I then found an arduino demo on infineons website here:

Boards and Shields for Arduino - Infineon Technologies

Infineon-Arduino_Getting_Started_Examples.exe-GS-v01_00-EN

You download a windows installable, which upon execution places a zip in install directory, and then you need to extract the zip, so you can get a single arduino ino file !

Why all this trouble, for a source file!? I think this is a good oportunity to introduce https://codebender.cc/

It's an online arduino IDE, which you can even compile a sketch and upload directly to your arduino from the browser.

And here is the infineon rgb demo source:
https://codebender.cc/sketch:105851

(I've tried to embed it, but element14 site does not like it I guess)

 

and this is the result:

Hans was still thinking about the Wolf as he headed into town to get supplies. It was a nice day so he decided to wander down the side of the stream. As he passed the mill he looked up at the water wheel. The stream had been diverted into a wooden channel to power the wheel and then following the mill pond it rejoined the main flow.

 

"If I use a VPN client on the Yun then I could control my own channel to the weather service", he thought. When Hans reached the market he posted a letter to the weather service explaining his idea, bought the provisions and headed home.

 

VPN.png

 

Special Delivery

 

A few days later there was a knock on the door. "Hello", said the uniformed man. "You're not our usual postman" said Hans. "No", said the man, "he's off sick so I've come from the next town to stand in", and he handed Hans a letter.

 

The letter was sealed with a red wax seal with a big Y!. Inside was a paper with an official header on it that he instantly recognised. It was a letter from the weather service and it was not the news that Hans wanted to hear. Yes they could provide a VPN but it would need extra equipment installed in their office so would cost Hans 1000 gold coins per month. Hans and Matilda could not afford that but there must be another way.

 

Hans thought about the sealed envelope and the company identifier and wondered if the Yun could be configured for HTTPS connections. Simply adding the "s" to the end of the URL returned nothing so he added an extra parameter to try to capture the error stream back to the Arduino.

 

#include <Process.h>
void setup() {
  // Initialize Bridge
  Bridge.begin();

  // Initialize Serial
  Serial.begin(9600);

  // Wait until a Serial Monitor is connected.
  while (!Serial);

  // run various example processes
  runCurl();
}

void loop() {
  // Do nothing here.
}

void runCurl() {
  // Launch "curl" command and get Arduino ascii art logo from the network
  // curl is command line program for transferring data using different internet protocols
  Process p;        // Create a process and call it "p"
  p.begin("curl");  // Process that launch the "curl" command
  p.addParameter("https://query.yahooapis.com/v1/public/yql?q=select%20item.condition.text%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Chicago%20IL%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"); // Add the URL parameter to "curl"
  p.addParameter("&2>1"); // should pipe error output to stdout but does not
  p.run();      // Run the process and wait for its termination

  while (p.available()>0) {
    char c = p.read();
    Serial.print(c);
  }
  // Ensure the last bit of data is sent.
  Serial.flush();
}







 

That did not work so Han's tried a different approach using runShellCommand because the "&2>1" may need to be interpreted by the shell.

 

#include <Process.h>
void setup() {
  // Initialize Bridge
  delay(2500);
  Bridge.begin();
  // Initialize Serial
  Serial.begin(9600);
  // Wait until a Serial Monitor is connected.
  while (!Serial);
  Serial.println("Running Curl");
  // run various example processes
  runCurl();
  Serial.println("Done");
}
void loop() {
  // Do nothing here.
}
void runCurl() {
  Process p;        // Create a process and call it "p"
  p.runShellCommand("curl \"https://query.yahooapis.com/v1/public/yql?q=select%20item.condition.text%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Chicago%20IL%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys\" 2>&1");
  while (p.available()>0) {
    char c = p.read();
    Serial.print(c);
  }
  // Ensure the last bit of data is sent.
  Serial.flush();
}





 

This displayed the following error message:

 

Running Curl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
Done





 

Hans installed the certificates into /etc/ssl/certs using the package manager.

opkg update
opkg install ca-certificates




 

However the problem persisted.

 

After several hours of reading and googling the solution was found on the OpenWRT forum.

 

"The ca-certificates package is missing the HASH-links to the certificates"

https://forum.openwrt.org/viewtopic.php?id=50661

 

These can be added using openssl-util and a shell script provided in that article

 

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

# 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




Hans fired up the Arduino Serial monitor and the script returned the forecast, it was going to be a great day!

Success.png

Hans was now happy that he had secure end to end communications.

Reference:

http://curl.haxx.se/docs/sslcerts.html

http://wiki.openwrt.org/doc/howto/wget-ssl-certs

 

Next: Enchanted Objects Design Challenge - The snake, the troll and the fighting dwarves

20150416.jpeg

 

In post 6 I made a breadboard prototype of the speed signal circuit. I made a KiCAD layout and sent my fab files to oshpark.com.

My PCBs arrived yesterday. This is the story of the build and test.

 

Photo 16-04-15 13 42 22.jpg

 

Let's start with a short recap of the sensor schematic.

 

The Sensor Setup

 

irsetup.jpg

The infrared light from the optocoupler that's mounted under one of the pulleys of the turntable drive gets reflected once per rotation,

because I mounted a tiny mirror on the underside of that pulley. We're going to measure how much time there is between two reflections.

 

 

The Sensor Circuit and PCB

 

schema_kicad.png

 

My other post has a breakdown of the circuit, with signals before and after amplification. Let's check here how it turns out when the final circuit is finished.

When you order PCBs from oshpark.com, you get a preview. I'm putting that against the real ones here.

 

large_i.pnglarge_i back.pngPhoto 16-04-15 13 42 22_edited.jpg

 

You can see here that the predicted result very well matches the PCBs that you get.

 

SMD Solder Time

 

I used a pizza oven to solder. My technique for simple boards is quite basic.

I put paste on the pads, put the parts on, preheat the oven a bit (to 50° C), put the board in, look through the window to see what's happening, open the door when it looks okay.

 

shifted.jpg

 

My components are 1206 and SOT-23.

For some reason the transistor decided to move on the board. It ended up with the emitter on the base pad, and the base pin sitting where there is no pad.

I had to rework it with hot air, but all turned out well.

IMG_4346_lr.jpg

 

The Test

 

I checked all connections with a multimeter to see if all was right, and double-checked the transistor because it has been heated three times (oven, hot air to remove, hot air to solder it on again).

All was ok, and I connected it up to the IR optocoupler.

I connected my scope for a quick validation. All worked from the first try.

 

scope.jpg

 

I got a perfect signal. Because the inverting amp is so closely mounted to the sensors, the signal is also a bit nicer than with the breadboarded and Veriboarded setups.

 

capture_ohspark_pcb.jpg

 

Finally some simple but real electronics have entered the design.

 

What's happening with the Arduino Kit?

 

I've given it to one of my kids. She's going to work through the workshops. She promised to take photos and videos along the way.

Here's the second activity: A dimmer that is controlled from Processing

 

 

 

 

arduino1.jpg

arduino2.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'm currently building the "hardware" of the hat, so before posting a complete update, let's talk a little about the mind of the hat...

 

One of the most common complaints of Arduinos is their lack of connectivity. You build these cool hardware hacks, but then you can’t make them apart of the Internet of Things (IoT) unless you plug in a bulky Arduino WiFi shield.

The Arduino Yun solves that problem. The Yun is an Arduino with WiFi built in. Additionally, the Yun has a second microprocessor that runs a lightweight version of Linux and comes with Python preinstalled. However you can install Ruby, Node or PHP...

 

Overview of Arduino Yun

The Yun’s primary components are:

  • Atmel ATmega32U4 – this is the “Arduino chip” that controls the pins and lets you do all the hardware hacking that you associate with Arduinos. When you send a sketch (Arduino code) to the Yun via the Arduino IDE, it’s running on this chip.
  • Atheros AR9331 – This is the “Linux and WiFi chip.” It runs OpenWRT, “a Linux distribution for embedded devices.”
  • Three ports: a standard USB, a micro USB, and an ethernet port
  • Three buttons: WiFi reset, “Arduino chip” reset, and “Linux chip” reset. You’ll use the WiFi reset most often.
  • A microSD slot for external storage

 

Note: If you hold down the Arduino’s WiFi reset button for more than 30 seconds, your Yun will reset to factory conditions! (Though, if you’ve upgraded OpenWRT, the new version will remain.) If you hold the WiFi button for more than 5 seconds but less than 30, it will reset the WiFi networking settings.

 

Upgrade OpenWRT-Yun

Your Yun ships with a lightweight version of Linux called OpenWRT-Yun. In the time that has passed since your Yun shipped off the factory line, a newer and better version of OpenWRT-Yun has been released.

You’re going to save yourself a lot of headache if you upgrade to the latest version of OpenWRT-Yun now. (If you want to know all the details of why, check out the OpenWRT release notes). This process will take less than ten minutes.

  1. Visit the Arduino Software page
  2. Scroll halfway down the page
  3. Click the link for the OpenWRT-Yun upgrade image

xx - Yun download.png

  1. Drag the zip file onto the root of the SD card (you do not need to extract it)
  2. Eject the SD card, remove it from your computer, and plug it into the Yun
  3. Now we’ve got an OpenWRT image lying in wait on our SD card. Let’s fire up the Yun.

 

Connect to the Ardunio Yun over Wifi

If you have not previously connected your Yun to WiFi, it will create its own WiFi hotspot. You’ll connect your computer directly to the Arudino’s WiFi, open up the control panel in a browser, configure the Yun to connect to the wireless network of your choosing, then meet it back on that network.

  • Plug the small end of the micro USB cable into your Yun and the other end into your computer
  • Wait about 60 seconds for the Yun to boot up. When the Yun’s ready to go, you’ll see the white USB LED turn on.
  • On your laptop, check the available WiFi Networks for a new one called something like: ARDUINO-YUN90XXXXXX.
  • Once you’ve connected to your Arduino’s WiFi, open a browser and visit arduino.local. If that doesn’t work, visit 192.168.240.1 (I’m not sure why, but I found the former to be flakey). When asked for a password, enter “arduino”

 

xx - Yun home.png

 

Connect your Arduino WiFi

Once your Arduino Yun reboots:

  • ensure you’re still connected to the Arduino YUN-09XXXX WiFi network
  • revisit arduino.local or 192.168.240.1
  • click the Configure Button in the top right. Here you can:
    Change the name of your Arduino Yun
    Change the password
    Connect your Arduino to a WiFi network.
  • Select your WiFi network from the dropdown and carefully enter your password. If you get the password wrong you will not get an error message. If your Arduino reboots but you still see its Arduino Yun-902XXXX as an available option, there’s a good chance you typed in the wrong WiFi password.

 

xx - Yun configure.png

 

When all the settings are to your liking, click Configure and Restart. While you’re waiting, switch your laptop over to the WiFi network you just punched in to your Arduino Yun and wait for it to join you there.

 

Install the Arduino IDE

The last bit of setup is to install the Arduino IDE on our computer. This will let us write Arduino programs that will interact with the pins on the board so that we can do the kind of things that you associate with a traditional Arduino.

Make sure you have either Java 6 or Java 7 installed on your machine. If you don’t, download and install Java 7. (Java is currently at version 8, though the Arduino IDE seems to only support 6 or 7.)

Visit the Arduino software page and download the latest Arduino IDE.


This file is about 150 MB. After it downloads, install it, then open the Arduino IDE. Then we need to do two things to set up the IDE to work with your Yun:

First, click Tools -> Board and select Arduino Yun.

 

xx - Yun board.png


Second, click Tools -> Port and select the option with the IP address (it’s probably the last one).

From now on, you can build and download applications as on any other Arduino board!

Over the weekend just gone by I managed to create an Ubuntu boot disk and get the SAMA5D4 running with an operating system that provides me with

features I am a little more used to vs the Poky build that Atmel provide.

 

What I built was Ubuntu 14.04.1 LTS compiled and running on the SAMA5D4 Xplained Ultra board. Along with supporting root file system.

Thankfully this include apt-get and I have been able to install all my favourite tools, including a GCC compiler tool chain directly to the

board.  I really enjoying developing directly on single board computers so this is pretty useful for me.

 

I used a lot of web references to help me along my journey.

Prior to visiting the site below I set up an Ubuntu virtual machine, installed the Ubuntu kernel source and installed the gnu toolchain cross

compiler for ARM. That was all without references and actually managed to create a zImage file in a little under an hour. Most of the time

was spent downloading the AT91 source code.

 

The most useful site which gave me a lot of clues was the page for Robert Nelsons EEWIKI website that contains the info for the SAMA5D4EK.

 

Prior to finding that site I was a bit hooked up on the boot manager and couldn't make it work terribly well.

 

So his U-BOOT section was a great guide into getting things rolling a little more smoothly.

I could only get so far in the process until it hung and would go no further.

 

I won't replicate his site here as the steps are quite easily to follow and I've been through his entire process and got it working as well.

The process is quite lengthy though if you want to build your own kernel image, put a couple of hours aside to do it.

 

One of the most important files to modify was uEnv.txt

It contains a large number of boot parameters, but one line in particular was very important in getting this board up and running.

It was the primary board identifier for the device tree.

you have to make sure you include the line

 

fdt_file=/dtbs/at91-sama5d4_xplained_hdmi.dtb

 

<youtube video coming soon for the actual boot process>

 

You don't necessarily need to use the hdmi device tree, but it will add the framebuffer to /dev for you, which means you can tinker

with getting the HDMI screen running. I admit I have had it working, but not as a console display its not easily plumbed into place like on a Raspberry Pi.

 

I managed to draw a lot of colourful pixels to it using the command cat /dev/urandom > /dev/fb0

I found I needed to sometimes plug and unplug the HDMI cable to make it recognize the monitor was there.

sama5d4-hdmi-output.png

 

Now that i have Ubuntu on the board I'll be able to continue with my project and install RabbitMQ, as this will be the crux of my message bus/handler for

my IoT cloud based edge router and it will be processing all the data from my IoT devices.

 

If you would like to get hold of the Ubuntu image I created, you can download it from Dropbox.

It's designed to fit onto an 8GB SD card. Just use your favourite image burning software to burn it to the card.

On Windows  I use Win32 Disk Imager for Ubuntu, dd also works just fine.

I noticed that a couple of us are looking at the weather. I think I can get all I need from the Yahoo service so I'll go with that for the moment.

https://developer.yahoo.com/weather/documentation.html

 

Here's a couple of articles on other APIs that could be useful, particularly if you need your weather in other languages.

 

http://superdevresources.com/weather-forecast-api-for-developing-apps/

http://michaelwelburn.com/2011/11/02/comparing-weather-apis/

Whilst Matilda was planning and rebuilding Hans hit the books to study the new electronics they were going to add to their house. Hans was having trouble understanding the Yun parts, "why does it need two processors on one board?" he thought to himself.

    

Dinner at the Sprats'

 

Hans and Matilda were lucky to have kind neighbours and everyone has helped them out following the fire. One the night they visited their friends Mr and Mrs Sprat. When it came to dinner, Mr Sprat carved up a roast duck. Hans and Matilda were served the best slices of breast meat. On his wife's plate he placed a leg covered in a rich crispy skin. On his own plate were placed the dry pieces that had been a bit overcooked. At the end of the meal there was nothing left but bones. After dinner Mrs Sprat mentioned that she'd heard in the market place that the Wolf was planning to interfere with their weather reporting but was not sure how.

 

Fun with the Yun

 

The following day Hans was studying the Yun manual again and he thought of Jack Sprat and his wife. The Yun was made up of two parts, an Atmel ATMega microcontroller designed to interface to sensors and the real world and an Atheros processor running router software to connect to the WiFi and internet. Complementary functions fulfilled by each part.

BridgeBlockDiag.png

 

Useful links

 

PighiXXX – Yun Pinout

Linino wiki - upgradeimage
Arduino - YunUBootReflash

 

Checking the weather

 

The there was a curl example in the ArduinoYun Getting Started Guide that looked appropriate "It should be simple to modify this to connect to the weather service", he thought.

 

#include <Process.h>
void setup() {
  // Initialize Bridge
  Bridge.begin();

  // Initialize Serial
  Serial.begin(9600);

  // Wait until a Serial Monitor is connected.
  while (!Serial);

  // run various example processes
  runCurl();
}

void loop() {
  // Do nothing here.
}

void runCurl() {
  // Launch "curl" command and get Arduino ascii art logo from the network
  // curl is command line program for transferring data using different internet protocols
  Process p;        // Create a process and call it "p"
  p.begin("curl");  // Process that launch the "curl" command
  p.addParameter("http://arduino.cc/asciilogo.txt"); // Add the URL parameter to "curl"
  p.run();      // Run the process and wait for its termination

  // Print arduino logo over the Serial
  // A process output can be read with the stream methods
  while (p.available()>0) {
    char c = p.read();
    Serial.print(c);
  }
  // Ensure the last bit of data is sent.
  Serial.flush();
}














 

swapping out the URL parameter with one for the for the weather in Chicago

 

http://query.yahooapis.com/v1/public/yql?q=select%20item.condition.text%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Chicago%20IL%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys



 

produced a JSON result with the weather conditions that would need to be parsed.

 

{"query":
    {"count":1,"created":"2015-04-10T10:24:59Z","lang":"en-GB","results":
       {"channel":
          {"item":
             {"condition":
                 {"text":"Cloudy"}
             }
          }
       }
   }
}



 

Based on his experiments Hans sketched up a class diagram for the software.

ClassDiagram.png

Thoughts of the Wolf

 

Hans smiled as the message appeared on his screen but his thoughts soon turned to the Wolf. How could he be sure that the server he was connecting to was the real server? How could he ensure his request had not been tampered with and how did he know that the response was legitimate?

 

Next: Enchanted Objects Design Challenge - Channels and a special delivery to the Enchanted Cottage

The Internet of Things will be built on a base-layer of Internet-connected “Smart Objects”. However, there is a growing discomfort among individual users about being surrounded by Objects that collect information and then send it to who knows where to be shared with who knows who to be used for who knows what. There is growing alarm about Objects being used to spy on people, about smart home and smart car technology being hacked for break-ins and hijackings. Could somebody hack my smart thermostat data to identify when my house is unoccupied? Could somebody remotely lock me into my driverless car and kidnap me? With lots of Internet scare stories about strangers shouting out of web-connected baby-monitors and implanted medical devices being taken over remotely, such discomfort and alarm are very understandable.

 

As technologists, we perhaps tend to think that technology is a sufficient end in itself – that using technology to do something interesting or make something new is enough. However, for the Internet of Things to work, we need to go a few steps further: we need to ask ourselves questions such as “How can I reassure the user that this Object is safe and secure to use?”, “How can I make my Object so Enchanting that the user is happy to accept the added risk of having an Internet-connected Object in their lives”? People are happy to accept that their computers and phones are connected to the Internet but anti-virus and firewall software acts as a “comfort blanket” . Such a comfort blanket is not, however, available with many Objects.

 

How do we overcome these concerns? The first step is to ensure that the Object adds real value to the user’s life – this could be in terms of its practical functionality, its ease of use, its personal benefit or its aesthetics but, ideally, all four. All Objects will have functionality but we technologists again need to look beyond this. The withdrawn Google Glass could be viewed as having good functionality and relatively good ease-of-use but poor aesthetics and, as all too readily-identifiable Glass public users faced growing hostility, the opposite of personal benefit[1]. If an Object can hit all four areas of value, the user is more likely to be interested in being convinced how we technologists have made the Object private, safe and secure to use. With HealthKit, as with many of their products, Apple hit functionality, personal benefit, ease of use and aesthetics but users still had many concerns about data privacy and security[2] and Apple have been taking urgent action to reassure users.

 

It’s a very big challenge for Object designers: functionality, ease of use, personal benefit and aesthetics PLUS privacy, security and safety – and all of these across the many different application domains for the IoT. This is why phrases like “User Experience (UX)” and “Human Centred Design” are increasingly being heard in IoT discussions. In the Nimbus Centre where I work, our Smart Object development teams always include different varieties of technologist but may also include application domain experts, users, creative designers, UX designers, psychologists and sociologists. As technology specialists, we can’t hope to be expert in all of these topics but we do need to at least understand the importance of taking their influence into account in the Object design process and reach out for expert help as needed.

 

 


[1] http://www.forbes.com/sites/andrewcave/2015/01/20/a-failure-of-leadership-or-design-why-google-glass-flopped/

[2] (http://www.forbes.com/sites/dandiamond/2014/09/08/can-apples-healthkit-protect-your-data/)

A quick video of the servo and mechanism all connected up. I've spotted an interesting issue with these positional servos. When they power up the driving software has no idea where the servo is position so it will send the signal representing the centre position (which is configurable). The servo will move to that position as fast as it can even it it's right at the limits of it's positioning. Only after it reaches that point can the software attempt to control the speed of motion by sending a series of positions with delays between them.

 

 

This should be the last of the mechanical based posts and I'll switch onto electronics and software.

Hopefully there will be another installation of Hans and Matilda tomorrow but it might be delayed until slightly later in the week.

I've been able to connect to the SAMA5D4 with SSH and SCP. This post describes the steps I took to get there.

They are a redo of what peteroakes shows in his SAMA5D4 Xplained Ultra - Tips and Tricks #1 - Getting Displays up and Running video,

mixed in with moral support and a nodge in the right direction from clem57.


I've blogged about my first steps with the kit, Review 1: Unboxing and First Steps.

The second review was on cross compilation on a Windows machine: Review 2: Building the Libraries from Source

My third article was to get the board connected to my network: Review 5: TCP/IP running

 

 

winscp.png

 

I downloaded and extracted linux4sam-poky-sama5d4_xplained_hdmi-4.6.

Then I plugged an USB cable in the USB A Device input.

I placed JP7 (BOOT_DIS) and plugged the board in one of my computer's USB connectors.

I opened the device manager and changed the driver for the device to the AT91 USB Serial . On my pc it comes up with a different driver bu default.

I removed JP7.

I edited demo_linux_nandflash_hdmi.bat to set my com port (\USBserial\COM27), and executed it.

I've attached the load log. Here's a  summary:

 

-I- Waiting ...
-I- TCL platform : Windows NT
-I- SAM-BA 2.15  on : windows
-I- current connection is \USBserial\COM27, \\USBserial\\COM27 to be matched 
-I- Retrieved arguments from command line :
-I- argv 0 : \USBserial\COM27
-I- argv 1 : at91sama5d4x-ek
-I- argv 2 : demo_linux_nandflash_hdmi.tcl
-I- Connection \USBserial\COM27
-I- Connection : \USBserial\COM27 (target(comType) = 0)
-I- Board : at91sama5d4x-ek
-I- Traces Level : 4
-I- target(handle) : 50740032
-I- sourcing board description file C:/Program Files (x86)/Atmel/sam-ba_2.15/sam-ba.exe/../tcl_lib/at91sama5d4x-ek/at91sama5d4x-ek.tcl
Read device Chip ID at 0xFC069040 --- get 0x8a5c07c0
-I- Found chip : at91sama5d4x_0 (Chip ID : 0x8a5c07c0)
-I- Loading applet applet-lowlevelinit-sama5d4x.bin at address 0x200000
-I- Memory Size : 0x0 bytes
-I- Buffer address : 0x4
-I- Buffer size: 0x0 bytes
-I- Applet initialization done
-I- Low level initialized
-I- External RAM Settings :  extRamVdd=0, extRamType=1, extRamDataBusWidth=16, extDDRamModel=1
-I- Loading applet applet-extram-sama5d4x.bin at address 0x200000
-I- Memory Size : 0x20000000 bytes
-I- Buffer address : 0x200A00
-I- Buffer size: 0x0 bytes
-I- Applet initialization done
-I- External RAM initialized
-I- Command line mode : Execute script file : demo_linux_nandflash_hdmi.tcl
-I- === name before swith at91-sama5d4 ===
-I- === socName is at91-sama5d4 ===
-I- Chip variant is at91-sama5d4
-I- Board variant is _xplained_hdmi
-I- === ecc before swith at91-sama5d4 ===
-I- === eccType is 0xc1e04e07 ===
-I- === Initialize the NAND access ===
-I- NANDFLASH::Init (trace level : 4)
-I- Loading applet applet-nandflash-sama5d4x.bin at address 0x20000000
-I- Memory Size : 0x20000000 bytes
-I- Buffer address : 0x20024DF4
-I- Buffer size: 0x40000 bytes
-I- Applet initialization done
-I- === Enable PMECC OS Parameters ===
   - HEADER value  is 0xC1E04E07
-I- Pmecc header configration successful
-I- PMECC configure c1e04e07
-I- === Erase all the NAND flash blocs and test the erasing ===
-I- GENERIC::EraseAll
-I- === Load the bootstrap in the first sector ===
Sending boot file done.
-I- === Load the u-boot in the next sectors ===
-I- Send File u-boot-sama5d4_xplained_nandflash.bin at address 0x00040000
GENERIC::SendFile u-boot-sama5d4_xplained_nandflash.bin at address 0x40000
-I- File size : 0x4B7E8 byte(s)
-I- Complete 0%
-I- Writing: 0x40000 bytes at 0x40000 (buffer addr : 0x20024DF4)
-I- 0x40000 bytes written by applet
-I- Complete 84%
-I- Writing: 0xB7E8 bytes at 0x80000 (buffer addr : 0x20024DF4)
-I- 0xB7E8 bytes written by applet
-I- === Load the u-boot environment variables ===
-I- Send File ubootEnvtFileNandFlash.bin at address 0x000c0000
GENERIC::SendFile ubootEnvtFileNandFlash.bin at address 0xC0000
-I- File size : 0x20000 byte(s)
-I- Complete 0%
-I- Writing: 0x20000 bytes at 0xC0000 (buffer addr : 0x20024DF4)
-I- 0x20000 bytes written by applet
-I- === Load the Kernel image and device tree database ===
-I- Send File at91-sama5d4_xplained_hdmi.dtb at address 0x00180000
GENERIC::SendFile at91-sama5d4_xplained_hdmi.dtb at address 0x180000
-I- File size : 0x4648 byte(s)
-I- Complete 0%
-I- Writing: 0x4648 bytes at 0x180000 (buffer addr : 0x20024DF4)
-I- 0x4648 bytes written by applet
-I- Send File zImage-sama5d4 at address 0x00200000
GENERIC::SendFile zImage-sama5d4 at address 0x200000
-I- File size : 0x2CA7F8 byte(s)
-I- Complete 0%

...


-I- Complete 99%
-I- Writing: 0x40000 bytes at 0xB740000 (buffer addr : 0x20024DF4)
-I- 0x40000 bytes written by applet
-I- Complete 99%
-I- Writing: 0x40000 bytes at 0xB780000 (buffer addr : 0x20024DF4)
-I- 0x40000 bytes written by applet
-I- === DONE. ===

 

That's it. After rebooting I got this version info:

 

Linux version 3.10.0+ (josh@melon) (gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-12ubuntu1) ) #1 Wed Nov 5 17:30:56 CST 2014

 

I can use Putty to SSH into linux, and WinSCP to transfer files.

 

putty.png

 

You just have to accept the server signature the first time you log on, and you're done.

 

And that's it. Another step to getting executable code on the board.

I'll now focus on building a first C program ("Hello, world!") and test my cross-compile skills - my development pc is a Windows machine.

I've blogged about my first steps with the kit, Review 1: Unboxing and First Steps.

The second review was on cross compilation on a Windows machine: Review 2: Building the Libraries from Source

 

success.jpg

 

This time I connected the board to my home network.

That wasn't difficult at all.

At first I plugged the network cable from router to board while it had already booted.

The network was detected:

 

Oct 30 08:29:16 sama5d4-xplained kernel: macb f8020000.ethernet eth0: link up (100/Full)

 

I didn't get a lease. When I asked linux what my  ip address was, I only got the localhost:

 

root@sama5d4-xplained:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 2a:30:59:a4:17:10 brd ff:ff:ff:ff:ff:ff

 

 

A simple reboot with the cable connected gave me an ip address

 

root@sama5d4-xplained:~# /sbin/ifconfig
eth0      Link encap:Ethernet  HWaddr 96:73:72:46:14:ab
          inet addr:192.168.1.50  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:30 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2375 (2.3 KiB)  TX bytes:788 (788.0 B)
          Interrupt:22


lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:700 (700.0 B)  TX bytes:700 (700.0 B)

 

I was also able to ping other computers in  my network:

 

root@sama5d4-xplained:~# ping 192.168.1.27
PING 192.168.1.27 (192.168.1.27) 56(84) bytes of data.
64 bytes from 192.168.1.27: icmp_seq=1 ttl=128 time=91.3 ms
64 bytes from 192.168.1.27: icmp_seq=2 ttl=128 time=4.80 ms
64 bytes from 192.168.1.27: icmp_seq=3 ttl=128 time=2.83 ms

 

and the board shows up on my router's status page

ethernet.jpg

 

I was able to connect to the board via a browser from another pc. It shows an "It works!" message (see the first picture).

 

Next Steps:

 

I couldn't get a telnet or ssh session into the board yet. Putty says "Network error: Connection refused"

I'll have to do some more digging to see how I can get that to work on the distro that's on the board, and what I need to do to get this running.

 

This may be my next step up in getting my cross-compiled programs installed and running on the linux distro.

Reading patient's heart rate is the first step to get a more useful physical parameter: blood pressure


The idea I want to develop in this challenge is to tighten the finger until the sensor is no longer able to read heart beat. At that point, the pressure that lace is equal to the blood pressure. Typically, the blood pressure measurement units use a cuff that is pumped by a small compressor. To save weight and reduce the building cost of the MagicHat, I will try a different approach: a servo will pull an elastic string until the blood stops flowing in the finger. At that point, the force exercised by the lace is measured by means of a Force Sensing Resistor (FSR for short)

A Force Sensing Resistor is a device whose resistance decreases with the force applied on the sensor surface. A typical graph of the sensor resistance versus applied force is shown below


07 - Resistance vs force.png

 

The easiest way to measure a resistive sensor is to connect one end to Power and the other to a pull-down resistor to ground. Then the point between the fixed pull-down resistor and the variable FSR resistor is connected to the analog input of a microcontroller such as an Arduino (shown).


07 - Fritzing FSR.png

 

07 - FSR Circuit.gif

 

In this configuration the analog voltage reading ranges from 0V (ground) to about 5V (or about the same as the power supply voltage)

The way this works is that as the resistance of the FSR decreases, the total resistance of the FSR and the pull-down resistor decreases from about 100Kohm to 10Kohm. That means that the current flowing through both resistors increases which in turn causes the voltage across the fixed 10K resistor to increase.

The easiest way to determine how your FSR works is to connect a multimeter in resistance-measurement mode to the two tabs on your sensor and see how the resistance changes. Because the resistance changes a lot, a auto-ranging meter works well here. Otherwise, just make sure you try different ranges, between 1 Mohm and 100 ohm before 'giving up'.

 

Weight (g)

Force (N)

FSR Resistance

(FSR + R) ohm

Current thru FSR+R

Voltage across R

None

None

Infinite

Infinite!

0 mA

0V

20 g

0.2 N

30 Kohm

40 Kohm

0.13 mA

1.3 V

100 g

1 N

6 Kohm

16 Kohm

0.31 mA

3.1 V

1 kg

10 N

1 Kohm

11 Kohm

0.45 mA

4.5 V

10 kg

100 N

250 ohm

10.25 Kohm

0.49 mA

4.9 V

This table indicates the approximate analog voltage based on the sensor force/resistance w/a 5V supply and 10K pulldown resistor.

 

Note that our method takes the somewhat linear resistivity but does not provide linear voltage! That's because the voltage equation is:

 

Vo = Vcc ( R / (R + FSR) )


That is, the voltage is proportional to the inverse of the FSR resistance (see graph below)

 

07 - Vout vs Rm.png

After building the heart beat sensor, it's time to process the output signal to get the actual heart beat

 

The heart pulse signal that comes out of a photoplethysmograph is an analog fluctuation in voltage, and it has a predictable wave shape as shown in figure below

 

05 - Heart beat sensor signal.jpg

 

My goal is to find successive moments of instantaneous heart beat and measure the time between, called the Inter Beat Interval (IBI). By following the predictable shape and pattern of the PPG wave, we are able to do just that.

When the heart pumps blood through the body, with every beat there is a pulse wave (kind of like a shock wave) that travels along all arteries to the very extremities of capillary tissue where the Pulse Sensor is attached. Actual blood circulates in the body much slower than the pulse wave travels. Let's follow events as they progress from point 'T' on the PPG below. A rapid upward rise in signal value occurs as the pulse wave passes under the sensor, then the signal falls back down toward the normal point. Sometimes, the dichrotic notch (downward spike) is more pronounced than others, but generally the signal settles down to background noise before the next pulse wave washes through. Since the wave is repeating and predictable, we could choose almost any recognizable feature as a reference point, say the peak, and measure the heart rate by doing math on the time between each peak. This, however, can run into false readings from the dichrotic notch, if present, and may be susceptible to inaccuracy from baseline noise as well. There are other good reasons not to base the beat-finding algorithm on arbitrary wave phenomena. Ideally, we want to find the instantaneous moment of the heart beat. This is important for accurate BPM calculation, Heart Rate Variability (HRV) studies, and Pulse Transit Time (PTT) measurement. .

 

06 - PPG Output with notes.jpg

 

Some heart researchers say it's when the signal gets to 25% of the amplitude, some say when it's 50% of the amplitude, and some say it's the point when the slope is steepest during the upward rise event. This version 1.1 of Pulse Sensor code is designed to measure the IBI by timing between moments when the signal crosses 50% of the wave amplitude during that fast upward rise. The BPM is derived every beat from an average of the previous 10 IBI times.

First off, it's important to have a regular sample rate with high enough resolution to get reliable measurement of the timing between each beat. To do this, we set up Timer2, an 8 bit hardware timer so that it throws an interrupt every other millisecond. That gives us a sample rate of 500Hz, and beat-to-beat timing resolution of 2mS. This will disable PWM output on pin 3 and 11

 

void interruptSetup(){
 TCCR1A = 0x00;
 TCCR1B = 0x0C; 
 OCR1A = 0x7C; 
 TIMSK1 = 0x02; 
 sei();
}


 

The register settings above tell Timer2 to go into CTC mode, and to count up to 124 (0x7C) over and over and over again. A prescaler of 256 is used to get the timing right so that it takes 2 milliseconds to count to 124. An interrupt flag is set every time Timer2 reaches 124, and a special function called an Interrupt Service Routine (ISR) that we wrote is run at the very next possible moment, no matter what the rest of the program is doing. sei() ensures that global interrupts are enabled.

 

The only other thing you will need is the correct ISR vector in the next step. ATmega32u4 devices use ISR(TIMER1_COMPA_vect)

So, when the Arduino is powered up and running with pulse sensor plugged into analog pin 0, it constantly (every 2 mS) reads the sensor value and looks for the heart beat. Here's how that works:

 

ISR(TIMER2_COMPA_vect){ 
 Signal = analogRead(pulsePin); 
 sampleCounter += 2; 
 int N = sampleCounter - lastBeatTime; 


 

This function is called every 2 milliseconds. First thing to do is to take an analog reading of the Pulse Sensor. Next, we increment the variable sampleCounter. The sampleCounter variable is used to keep track of time. The variable N will help avoid noise later.

Next, we keep track of the highest and lowest values of the PPG wave, to get an accurate measure of amplitude. Note that this processing will be also useful when we will try to measure blood pressure

 

    if(Signal < thresh && N > (IBI/5)*3){
      if (Signal < T){ 
        T = Signal;    
      }
    }
    if(Signal > thresh && Signal > P){  
      P = Signal; 
    }


 

Variable P and T hold peak and trough values, respectively. The thresh variable is initialized at 512 (middle of analog range) and changes during run time to track a point at 50% of amplitude as we will see later. There is a time period of 3/5 IBI that must pass before T gets updated as a way to avoid noise and false readings from the dicroic notch.

Now, let's check and see if we have a pulse.

 

if (N > 250){
if ( (Signal > thresh) && (Pulse == false) && (N > ((IBI/5)*3) ){  
 Pulse = true; 
 digitalWrite(pulsePin,HIGH);            
 IBI = sampleCounter - lastBeatTime;
 lastBeatTime = sampleCounter;       


 

Before we even consider looking for a heartbeat, a minimum amount of time has to pass. This helps avoid high frequency noise. 250 millisecond minimum N places an upper limit of 240 BPM. If you expect to have a higher BPM, adjust this accordingly and see a doctor. When the waveform rises past the thresh value, and 3/5 of the last IBI has passed, we have a pulse! Time to set the Pulse flag and turn on the pulsePin LED. Then we calculate the time since the last beat to get IBI, and update the lastBeatTime.

The next bit is used to make sure we begin with a realistic BPM value on startup.

    

  if(secondBeat){ 
   secondBeat = false; 
   for(int i=0; i<=9; i++){   
     rate[i] = IBI; 
   }
 } 
if(firstBeat){ 
   firstBeat = false; 
   secondBeat = true;
   sei(): 
   return;  
 }




The boolean firstBeat is initialized as true and secondBeat is initialized as false on start up, so the very first time we find a beat and get this far in the ISR, we get kicked out by the return; in the firstBeat conditional. That will end up throwing the first IBI reading away, cause it's lousy. The second time through, we can trust (more or less) the IBI, and use it to seed the rate[] array in order to start with a more accurate BPM. The BPM is derived from an average of the last 10 IBI values, hence the need to seed.

Here is the code to calculate BPM

 

  runningTotal = 0;
  for(int i=0; i<=8; i++){
    rate[i] = rate[i+1]; 
    runningTotal += rate[i];      
  }
 
  rate[9] = IBI; 
  runningTotal += rate[9]; 
  runningTotal /= 10; 
  BPM = 60000/runningTotal;
  QS = true;  
}                      




First, we grab a large variable, runningTotal, to collect the IBIs, then the contents of rate[] are shifted over and added to runnungTotal. The oldest IBI (11 beats ago) falls out of position 0, and the fresh IBI gets put into position 9. Then it's a simple process to average the array and calculate BPM. Last thing to do is to set the QS flag (short for Quantified Self, awesome kickstarter supporters!) so the rest of the program knows we have found the beat. That's it for the things to do when we find the beat.

There's a couple of other loose ends that need tying off before we're done, like finding the not-beat.

 

if (Signal < thresh && Pulse == true){ 
  digitalWrite(13,LOW);         
  Pulse = false; 
  amp = P - T; 
  thresh = amp/2 + T;            
  P = thresh; 
  T = thresh;
}




Pulse was declared true during the upward rise in Pulse Sensor signal when we found the beat, above, so when the signal crosses thresh going down, we can figure that the pulse is over. A little housekeeping in clearing pulsePin and the Pulse boolean. Then the amplitude of the wave that just passed is measured, and thresh is updated with the new 50% mark. P and T are reset to the new thresh. The algorithm is now primed and ready to find the next beat.

There's one more question to ask before the ISR is done. What if there are no beats?

 

if (N > 2500){    
  thresh = 512; 
  P = 512; 
  T = 512; 
  firstBeat = true; 
  secondBeat = false; 
  lastBeatTime = sampleCounter;
  }


 

If there is no beat event for 2.5 seconds, variables used to find the heartbeat are reinitialized to the start up values. Sort of a soft soft-reset. That's the end of the ISR!

By using Timer2 interrupt, our beat finding algorithm runs 'in the background' and automatically updates variable values , Here's a list of useful variables, and how often they are updated.

  • Signal: raw pulse sensor signal, read every 2 ms
  • IBI: time between heartbeats in ms, refreshed every time a beat detected
  • BPM: beats per minute, refreshed every time a beat is detected
  • QS: set true every time a beat is detected, must be cleared by user
  • Pulse: set true every time a beat is detected, must be cleared by ISR

 

There you have the basic beat finding code. Having all the vital variables updated automatically makes it easy do stuff in the loop() function.

  

void setup() {
  pinMode(13,OUTPUT);  
  pinMode(10,OUTPUT);  
  Serial.begin(115200);  
  interruptSetup();      
  //  analogReference(EXTERNAL);  
 } 


 

Here we go. pulsePin is the analog pin number that Pulse Sensor purple wire is plugged into. You can change it if you need to. blinkPin will blink with the pulse. The fadeRate variable is used to provide an optional fading LED effect with every beat on fadePin (must be a PWM pin, but not 3 or 11). It looks nicer than the blink on pin 13. The other variables should look familiar to you now. They are declared volatile because they get used in the ISR and the other parts of the code. In the setup, pin directions are declared and the interruptSetup routine is run. The last line in setup is used only when you have a different voltage powering the Pulse Sensor than you are using to power the Arduino. Mostly, it should be commented out.

 

void loop() {
  if (QS == true){  
    fadeVal = 255;    
    QS = false; 
   }
   ledFadeToBeat();
   delay(20); 
}


 

Here's the loop function. Note the delay at the end. This loop will run every 20mS. Since Signal is updated automatically, you can do whatever you want with it as well, modulate a tone output on a speaker, etc.. Remember that the QS flag gets set when our ISR finds the heart beat, so by checking it we can know when the beat happens. Inside the if statement we set the fadeVal to maximum brightness and reset the QS flag for next time. the last thing to do before the delay is to fade the LED and then we're done with the loop.

 

void ledFadeToBeat() {
 fadeRate-= 15; 
 fadeRate= constrain(fadeRate,0,255);
 analogWrite(fadePin, fadeRate);            
 }



The ledFadeToBeat function is pretty simple too. It reduces the fadeRate variable by 15 (you can change this as needed), makes sure the fadeRate doesn't roll over into negative numbers,or get higher than 255, then uses analogWrite to set the brightness if the LED on fadePin.

I Just received Arduino Yun.

There was some delay due to Greek customs,  as it was send from the US,  but element14 took care of it, along with the expenses

Thanks! :-)

DSC_0133.JPG

 

So I power up YUN with a micro usb cable, and search for wifi. Found one named "Arduino YUN blahblahxxxxx", connected and tried surfing it on IP 192.168.240.1

And this is the welcome screen. (password is arduino)

yun-1.pngyun-2.png

 

I configured my Wifi SSID and pass, (would be usefull to have a tick-box for displaying pasword)

rebooted and I can see Yun on my accesspoint, getting an IP, great!

 

yun-3.pngyun-4.png

 

Did an ssh connection via putty, using root and arduino as pass, and here is the linino.

Downloaded arduino 1.6.3

Arduino - Software

Specified board as Yun, selected correct port, and uploaded the "blink" example... waiting...it works! :-)

All was straight forward and as expected, nice.

YunResetIllustrations.png

Note, if something goes wrong with your Wifi settings, you can:

  • hold the WiFi button for more than 5 seconds but less than 30, it will reset the WiFi networking settings.
  • or hold down the Arduino’s WiFi reset button for more than 30 seconds, and Yun will reset to factory conditions.

 

 

 

 

 

 

 

 

 

next >> [ExM] #4 First attempt with infineon RGB LED Lighting Shield XMC1202

 

 

crjeder

Identifying Keys

Posted by crjeder Apr 7, 2015

Crucial to my design is the ability to detect and identify keys. The potential solutions are divided into following categories: wireless, wired and explicit. The later means the user explicitly states „this is key #11“ through some interface. This is the least desired one and will be the fall-back if everything else fails. Therefore let's concentrate on the other two.


Wireless


Because of the popularity of RFID tags wireless identification was the technology I thought about first when looking for a solution to this problem. But there are many more which fall into two categories: active and passive wireless.


Passive Wireless

Passive Wireless is the “classic” RFID tag we see as labels on high priced goods every day. The RF chip is powered “over the air” by the reader which limits distance, data rate and processing power of such solutions. But for identification, data rate and processing power requirements are very low, thus cheap solutions will perform well in this scenario.

I did not know that there are different frequencies with different characteristics in RFID technology. The following table lists properties relevant in this project.


Frequency

 

Typical max sensing

Distance in m

Multiple Tags?

Problematic to Operate near Metal

125 kHz

Low Distance, slow, expensive tags

0.3

No

Yes

13,5 MHz

ISM Band used for Smart Cards and Memory cards also NFC

+ cheap tags

1

Yes

Yes

~800 – ~900 MHz

UHF

2

Yes

No

2.4 GHz

ISM Band is also used for Bluetooth, BLE, ZigBee, WiFi, etc.

1

Yes

No

 

NFC and contact less Smart Cards use the same frequencies. 13.5 MHz readers and tags are easily available and cheap. UHF readers are very expensive so despite their good properties they will be excluded. 2.4 GHz passive tokens seem to exist only in theory. Therefore the choice boils down to two alternatives 125 kHz and 13.5 MHz which will be tested for their ability to communicate when the tag hangs between the keys. The metal may shield the tag and reliable reading might not be possible.

I have ordered one 125 kHz reader and key fobs and a NFC / RFID Arduino shield to try the most promising solutions.

 

7129610357_a8c128d1d8_z.jpg

(Foto by Adafruit Industries)

Active Wireless

Active tokens are very similar to passive ones, only with a battery. This is of course very simplified, but is enough to get an idea. By actively powering the RF device many of the limitations of passive devices can be overcome. Plus RF technologies which are to power consuming for passive tags like WiFi and Bluetooth can be used. I was not able to find any passive token in the 2.4 GHz ISM band but there exist active ones. Because of size and weight constraints BLE tokens are most viable.


Wired


Wired solutions are often simpler and cheaper than wireless ones, but are less practical or convenient. My first idea to detect keys hanging on a hook was using switch which gets pressed or released by the weight of the keys. The detection part is really simple, more difficult is the identification. This has to be outsourced to the user: The hooks and key rings are marked with a colour and users have to hang their key on the respective hook. That violates my idea of how the user interface should be but would be a solution if everything else fails. (see explicit identification)

Since there is only one conductor between a key fob and the board 1-Wire devices came into my mind. Usually a circuit for 1-Wire looks like this:

 


1-wire-parasite_Schaltplan.png

But 1-Wire bus is a marketing lie: they do not count the ground wire!


 

1-wire-parasite_problem.png

The question now is where do we get the ground from?

 

I have two ideas which I have to test. First use the human body as ground. The mass should be big enough for the small charge which has to be transported (ca. 7 nano coulomb). The resistance of the skin can be several kilo Ohms which may be too much. Since I am not an electronics expert and everybody I’ve so far asked could not answer this question I have to try it. Parts are ordered, stay tuned for updates.

 

1-wire-parasite_finger.png

While testing it turned out that the human skin is a very bad conductor which makes this version impossible at least with 3,3 V.

Since this does not work I would insulate the hook form the board and use the board as ground. Not as elegant but should work.

 

 

1-wire-parasite_board.png

 

And indeed the keys are good enough conductors and when they are large enough they touch the board. So I have a solution!

Hi All,

 

My project synopsis for those who didn't see my application is quite basic in its theory. What I intend to do is create an IoT message bus and transaction system.

I will either roll my own, or something off the shelf with RabbitMQ and then build an API so that devices can readily communicate their results across the network

into the message queueing system and have them displayed in a portal.  Of course there are solutions out there that do this already, but there is no harm in rolling

your own proof of concept.  I want to do this so I can continue to customise my solution down the track and be able to control how I interact both from the client side and the

server side.

 

Now onto what I did over the Easter weekend long weekend..

 

Well I received my kit of parts from Element 14 and after building my new desk on Friday night I was finally in a position to get setup and start work on this design challenge.

Warning.. picture may contain traces of easter eggs... :-)

easter_goodies.png

My new corner L shaped desk. 2100mm x 2100mm x 750mm x 730mm (length x width x height)

desk1.png

 

I'd read a lot about the Atmel SADA5D4 and the trouble people were having, so I figured, let's give this a go. It can't be that hard, right?

Glad to see that people were not exaggerating. If you want a lesson in calm and patience, buy yourself one of these and try to figure out how to make

it work.  I managed to get the serial interface working so I could actually talk to the device and was able to build myself a new linux kernel based on Ubuntu.

Currently I am failing because my unix VM can't properly mount my SDCard, which means I can't easily write the OS to the card, but I'll overcome that in the next day or two, I hope.

 

The operating system installed on the SAMA5D4 is a huge disappointment. The implementation is severely lacking in those everyday tools which could have made

this SBC into a 5 star performer. Had they been able to bundle it with a more complete implementation of UNIX, or even standardised it a little more towards Debian and given us an install

where we could readily use a development toolchain it would have immediately changed how the board can be used. What they really need to do is re-evaluate the board

and enable the functionality that exists on the board via the various interfaces. A good example of this is the HDMI port.

If you are providing a HDMI port, at least include the necessary modules to allow the HDMI port to be used as a console.

 

I could see this card easily rivalling a Raspberry Pi 2 if a bit more forethought had been put into the software/operating system layer of the card.

 

Now there are a couple of useful tools installed, there is a http light server as well as python. I could probably use these to roll my own MQ, so even in its vanilla flavour, the SAMA5D4 may

prove to be useful yet. I just can't spend a lot of time working against the tools, I'd rather work with them.

20150406.jpeg

I've made a Digital Light Organ Enchantment for my Perpetuum-Ebner turntable last week.

To add a little cyberpunk touch to it, I'm creating a servo lift that will pop out the light effects when there is music.



I've titled it an autonomous lift because the logic is contained within a limited set of code.

You tell it to be up or down, and it will take care to achieve that state and stay there until told differently.

The servo is a small 180° common motor, not the 360° continuous servo.


Servo Lift Code

 

The lift logic is contained in a few methods. You only have to remember to call servoInit() in your setup() code, and call servoGo() at regular times (I've put it in the loop().

You tell the servo what state it should be in by setting the boolean variable servoUp to false (down) or true (up).

The servo will work by itself to fulfill your demand.

 

There are a few parameters you can tweak:

 

SERVO_BASE: the down position of the lift.

SERVO_TOP: the up position

SERVO_DELAY: milliseconds between steps to move up or down. Affects the rise and fall time of the light organ in my player.

 

#include <Servo.h>

Servo servo;

#define SERVO_PIN 9
#define SERVO_DELAY 25
#define SERVO_BASE 90
#define SERVO_TOP (SERVO_BASE - 61)

int servoPos = SERVO_BASE;
bool servoUp = false;

void servoInit() {
    servoUp = false;
    servo.attach(SERVO_PIN);
    servoPos = SERVO_BASE;
    servo.write(SERVO_BASE);
    delay(1000);
}

void servoGoUp() {
   if (servoPos > SERVO_BASE) {
    servoInit();
  }
    if (servoPos > SERVO_TOP) {
    servoPos--;
    servo.write(servoPos);
    delay(SERVO_DELAY);
  }
}

void servoGoDown() {
   if (servoPos > SERVO_BASE) {
    servoInit();
  }
    if (servoPos < SERVO_BASE) {
    servoPos++;
    servo.write(servoPos);
    delay(SERVO_DELAY);
  }
}

void servoGo() {
  if (servoUp) {
    servoGoUp();
  } else {
    servoGoDown();
  }
}





 

Test Bed Code

 

The sketch to exercise the lift is simple.

It waits for you to enter a command in the Arduino IDE Serial Monitor.

If you enter '1', the lift will go up slowly and stay there. If you enter '0' it will go down.

 

void setup()
{
  Serial.begin(9600);
  servoInit();
  Serial.println("Menu: Up: 1, Down: 0");
}

void loop()
{
  while (Serial.available() > 0) {
    servoUp = (Serial.parseInt() > 0);
  }
  servoGo();
}




 

The lift is supposed to go into the cable storage area of the Perpetuum-Ebner Musical 1.

Photo 06-04-15 10 11 21.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

The basement and extension

Hans and the woodcutter assembled the planks to form support frame for Matilda's mechanics. The woodcutter liked the minimalism of the wooden design, "everything should be made as simple as possible, but not simpler" he said before returning to the forest.

Framework.jpg

Hans and Matilda cleaned up the parts from the Blacksmith and polished the axles before putting them together with the screws. They checked that everything ran smoothly, some minor changes would be needed but the mechanism provided the motion that was desired.

MechanicsTest.jpg

Crows

After their hard work they decided to rest on a log and have some sandwiches. Whilst they were eating they spotted two crows collecting sticks for nest building. The large crow picked up big sticks and flew very fast, but the large sticks clashed on the branches so the crow had to take a long route around to get to the nest. The small crow took smaller twigs and hopped slowly between the branches reaching its nest more quickly.

 

After their lunch Hans and Matilda decided to test the servos. They had a large servo with a long horn and a very small servo with a small horn. Hans wanted to know the current consumption and Matilda wanted to know if they had enough torque to move the mechanism. Before starting their test they downloaded the latest Arduino IDE.

Arduino-IDE-1.6.2.jpg

To make the testing easier Matilda mounted the servos on a simple wooden test platform. Following the woodcutter's hint she connected these up to the test mechanism using bendy connecting rods.

 

 

#include <VarSpeedServo.h>

/*
Sweep
by BARRAGAN <http://barraganstudio.com>
Adapted by Philip van Allen <philvanallen.com> for the VarSpeedServo.h library (October 2013) https://github.com/netlabtoolkit/VarSpeedServo
This example code is in the public domain
Moves servo, 180-0 degrees
Uses the wait feature of the 2013 version of VarSpeedServo to stop the code until the servo finishes moving
Note that servos usually require more power than is available from the USB port - use an external power supply!
*/
VarSpeedServo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
const int servoPin = 9; // the digital pin used for the servo

void setup() {
  myservo.attach(servoPin); // attaches the servo on pin 9 to the servo object
  myservo.write(0,255,true); // set the intial position of the servo, as fast as possible, wait until done
}

void loop() {
  myservo.write(180,255,true); // move the servo to 180, max speed, wait until done
  // write(degrees 0-180, speed 1-255, wait to complete true-false)
  myservo.write(0,30,true); // move the servo to 180, slow speed, wait until done
}








The Wolf

 

From nearby in the forest, the wolf was watching and listening.

 

Next: Enchanted Objects Design Challenge - Yum Yum Yun at the Enchanted Cottage

crjeder

Happy Easter!

Posted by crjeder Apr 5, 2015

DSC_9209.JPG

I wish everybody a Happy Easter. Thanks Element14 for this cool competition and to all patient readers and to the helpfully and skilled participants.

Unfortunately there was not much progress on the competition from my side. But as an status update: I am looking for a solution to identify keys.

Here a sneak preview:

DSC_9220.jpg

DSC_9223.jpg

And to distract you from the challenge: Go outside it's spring! (ok, northern hemisphere only ;-)

P4032550.jpg

rpbruiser

As The Sunsets...

Posted by rpbruiser Apr 5, 2015

As the sunsets on the genie's home, he is curious as to what time it is, since he forgot to buy a clock. Silly him . Fortunately he had a smart home, and all he needed was internet for his house to tell him the time! But how? Well just say the magic word, and the genie will show you!


           "I WISH....."

 

First you have to find the longitude and latitude for where you live. The genie found it would be much easier to use an API that simply used your IP address to give you this!

 

String findLon() {
    HttpClient clientLon;
    clientLon.get("http://ip-api.com/csv/?fields=lon");

    while (clientLon.available()) {
      lon = clientLon.readString();
    }

    Serial.print("Lon: ");
    Serial.println(lon);

    return lon;
}


String findLat() {
    HttpClient clientLat;
    clientLat.get("http://ip-api.com/csv/?fields=lat");

    while (clientLat.available()) {
      lat = clientLat.readString();
    }

    Serial.print("Lat: ");
    Serial.println(lat);

    return lat;





 


Once the genie knows where he is, he now can figure out when the sunsets and rises, using an algorithm that can be found here.

   A = year() / 100;
   B = A / 4;
   C = 2 - A + B;
   E = 365.25 * (year() + 4716);
   F = 30.6001 * (month() + 1);
   JD = C + day() + E + F - 1524.5;
   JC = (JD - 2451545) / 36525;
   longSun = int(280.46646 + JC * (36000.76983 + JC * 0.0003032)) % 360;
   anomSun = 357.52911 + JC * (35999.05029 - 0.0001537 * JC);
   eOrbit = 0.016708634 - JC * (0.000042037 + 0.0000001267 * JC);
   sunEqCtr = sin(D2R * (anomSun)) * (1.914602 - JC * (0.004817 + 0.000014 * JC)) + sin(D2R * (2 * anomSun)) * (0.019993 - 0.000101 * JC) + sin(D2R * (3 * anomSun)) * 0.000289;
   trueLongSun = longSun + sunEqCtr;
   trueAnomSun = anomSun + sunEqCtr;
   sunRadVector = (1.000001018 * (1 - eOrbit * eOrbit)) / (1 + eOrbit * cos(D2R * (trueAnomSun)));
   sunAppLong = trueLongSun - 0.00569 - 0.00478 * sin(D2R * (125.04 - 1934.136 * JC));
   obliqEcliptic = 23 + (26 + ((21.448 - JC * (46.815 + JC * (0.00059 - JC * 0.001813)))) / 60) / 60;
   obliqCorr = obliqEcliptic + 0.00256 * cos(D2R * (125.04 - 1934.136 * JC));
   sunAscen = R2D * (atan2(cos(D2R * (sunAppLong)), cos(D2R * (obliqCorr)) * sin(D2R * (sunAppLong))));
   sunDeclin = R2D * (asin(sin(D2R * (obliqCorr)) * sin(D2R * (sunAppLong))));
   varY = tan(D2R * (obliqCorr / 2)) * tan(D2R * (obliqCorr / 2));
   eqTime = 4 * R2D * (varY * sin(2 * D2R * (longSun)) - 2 * eOrbit * sin(D2R * (anomSun)) + 4 * eOrbit * varY * sin(D2R * (anomSun)) * cos(2 * D2R * (longSun)) - 0.5 * varY * varY *
     sin(4 * D2R * (longSun)) - 1.25 * eOrbit * eOrbit * sin(2 * D2R * (anomSun)));
   haSunrise = R2D * (acos(cos(D2R * (90.833)) / (cos(D2R * (lati)) * cos(D2R * (sunDeclin))) - tan(D2R * (lati)) * tan(D2R * (sunDeclin))));
   if (daylight == true) {
     solarNoon = (720 - 4 * longi - eqTime + -5 * 60) / 1440; //TODO: Change -5 to a method for finding timezone
     solarNoon = solarNoon + .041667;
   }
   else {
     solarNoon = (720 - 4 * longi - eqTime + -5 * 60) / 1440; //TODO: Change -5 to a method for finding timezone
   }
   localRiseTime = (solarNoon * 1440 - haSunrise * 4) / 1440;


For sunset all you have to do is manipulate the local rise time to be the local set time by changing it like so:

localSetTime = (solarNoon * 1440 + haSunrise * 4) / 1440;



Unfortunately, this algorithm does not account for daylight savings time, which of course only applies to certain places, but the genie, residing in the US, decided he should account for it.

boolean isDaylightSavings() {
  int marchSecondSunday, novFirstSunday, cent, i, n;

  cent = floor(year() / 100);

  for (i = 8; i <= 14; i++) {
    if (marchSecondSunday != 0) {
      marchSecondSunday = int((i + floor(2.6 * 3 - 0.2) - 2 * cent + year() + floor(year() / 4) + floor(cent / 4))) % 7;
    }
    break;
  }
  for (n = 1; n <= 7; n++) {
    if (novFirstSunday != 0) {
      novFirstSunday = int((i + floor(2.6 * 11 - 0.2) - 2 * cent + year() + floor(year() / 4) + floor(cent / 4))) % 7;
    }
    break;
  }

  if (month() == 3) {
   if (day() >= i) {
     daylight = true;
    }
  }
  else if (month() == 11) {
   if (day() <= n) {
    daylight = true;
   }
  }
  else if (month() > 3) {
   daylight = true;
  }
  else if (month() < 11) {
   daylight = true;
  }
  else {
   daylight = false;
  }

  return daylight;
}



From here, the genie can also get the current time, and compare the two! and of course his house, the lamp, will shine bright if between the sunset and sunrise!

However, the electrician has not finished at the house, so as of right now, no lights .

 

                                                   image1.png

 

More to come...

The arrival of parcels is always exciting for me. Even if it is just an Amazon box containing an audio cable, I still get a little excited, so naturally, when this arrived at my door, I was VERY excited.

 

IMG_20150319_164745.jpg

The box arrived within a few days of the e-mail telling me that I had been accepted into the challenge. Considering that I am in the UK, this is especially impressive. Naturally, my first reaction was to open everything and lay it out onto my bed (I had just had guests and my desk was still not cleared). Strangely enough, the Arduino proto sheild came in a separate envelope from a UK warehouse in order to ship faster to the UK. It is nice to see that fast shipping is given such a priority. Unfortunately the Gun has not arrived yet, but everything else was included in the box. Also, kudos to Atmel for including a USB cable with the explained board. One of my micro B cables recently suffered some sort of internal failing, leaving it unable to charge my tablet at a reasonable speed. The new one is now a significant part of my cab.

IMG_20150319_164606.jpg

Strangely enough, I have never owned an Uno. My only Arduino up to this point has always been a Leonardo, thanks to the extra IO, reduced cost and keyboard emulation. I was really excited about the ease of use with extra library's and ability to swap chips. What I did not realise was how much faster it would be to upload sketches. Uploading sketches to the Leonardo is not too difficult after the first time, and did not expect the Uno to blow me away in this area. In reality, after the sketch compiled, it would upload several times faster on the Uno. I still like my Leonardo, but the Uno is going to be a valuable addition to my toolkit.


My first stage of testing was to remove the display from the meter's circuitry and hook it up to a 5v power supply to see if the dial would reach full deflection. Thankfully the dial had convenient positive and negative labels for the terminals. I briefly tapped the terminal and the dial immediately went off the scale. This may change my approach to the design for project. It may be possible to commit the motor driver and circuitry from the multimeter and instead drive the dial via a pwm pin from the Arduino via some resistors to limit the current. Of course this depends on the power required to drive the dial and whether the Arduino is capable of supplying the required current. If this is possible, then I may instead use the LED driver I was sent to implement a more interesting backlight.

IMG_20150319_175034.jpg

I also noticed that the cover for the display was held on only with sellotape. This potentially means I could remove the cover and polish out some of the scratches that it has picked up over the years. However, my experiences with polishing plastic have been universally disappointing. If you have any advice on how to polish it, or on any other aspects of the protect, please feel free to leave it in the comments section.


NOTE: My new computer setup is still causing me some issues in producing these blog posts. I will attempt to continue posting from my backup device but expect some delays in posts. Strangely enough, comments are not being impacted.

Hello everyone,

 

So I have been programming the Arduino for enchanted clock I'm building (Work in progress). I am still having issues with the SAMA5D4 Xplained, I may have to change to an RPi if time starts to get tight. I really don't want to do this as our sponsors have been very generous and I don't want to let them down.

 

So to update where I am at. I have decided that for the clock to stay in time due to the inconsistency in a wood clock, I have made a binary clock. This clock will be integrated with my wood clock and through servos it will re-set it to the correct time. Below is a picture of the Binary Clock on the breadboard working. I will make a PCB board cape for final product. The time on the Binary Clock will be seen as well as the wood clock time.

 

WP_20150404_002.jpg

 

 

Schematic:

Binary.png

Clock Code:

 

#include <Wire.h>
#include <RTClib.h>
#include <TimerOne.h>

byte numPins = 5;
byte ledPins[] = {2, 5, 8, 10, 12};

byte hourLeds[][2] = {{1, 3}, {3, 1}, {0, 3}, {3, 0}};
byte minLeds[][2] = {{4, 2}, {3, 4}, {2, 3}, {1, 2}, {0, 1}, {2, 0}};
byte secLeds[][2] = {{2, 4}, {4, 3}, {3, 2}, {2, 1}, {1, 0}, {0, 2}};

RTC_DS1307 RTC;

int hour, min, sec;

void setup()
{
  Wire.begin();
  if (! RTC.isrunning())
  {
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  Timer1.initialize(20000); // uS
  Timer1.attachInterrupt( refresh );
}

void loop()
{
  static long lastTick;
  long thisTick = millis();
  if (thisTick > lastTick + 500l) // every 0.5 seconds
  {
    DateTime now = RTC.now();
    hour = now.hour();
    min = now.minute();
    sec = now.second();
    lastTick = thisTick;
  }
  refresh();
}

void refresh()
{
  int s = sec;
  int m = min;
  int h = hour;
  for (int bit = 0; bit < 6; bit++)
  {
    if (s & 1)
    {
      setLed(secLeds[bit]);
     // delay(10);
    }
    s = s >> 1;
    if (m & 1)
    {
      setLed(minLeds[bit]);
    }
    m = m >> 1;
    if (h & 1 && bit < 4)
    {
      setLed(hourLeds[bit]);
    }
    h = h >> 1;
   }
   allOff(); // so last led not brighter
}

void setLed(byte pins[])
{
  byte plusPin = ledPins[pins[0]];
  byte minusPin = ledPins[pins[1]];
  allOff();
  pinMode(plusPin, OUTPUT);
  digitalWrite(plusPin, HIGH);
  pinMode(minusPin, OUTPUT);
  digitalWrite(plusPin, LOW);
}

void allOff()

  for (byte pin = 0; pin < numPins; pin++)
  {
    pinMode(ledPins[pin], INPUT);
  }
}

 

Servo controller and timing sensor to be programmed into the script, this is for the clock only (so far).

 

My big focus is on the wooden clock, this is a huge part in the whole project. I will update mid week with photos of the progress.

 

Dale & Chrystal Winhold

I've uploaded the OpenSCAD models for the Watt's linkage mechanism and also modelled the wooden parts although those were actually cut by hand.

 

https://github.com/Workshopshed/EnchantedObjects

BeamWithPins.png

WoodParts.png

In Part 1 I reviewed the servo and made a test bed for prototyping. I'll continue with some stats and measurements.



Dead Band

 

The continuous servo has a range of angles, around 90, where it doesn't rotate. Calling Servo.write() with a value in that dead band makes the motor stop.

On mine that band is between 89 and 94. The few values below and above that range cause some noise in the motor, but it doesn't start to spin yet.

It spins under 87 and above 96.


Servo Signal


Servos are controlled with a PWM signal. The duty cycle defines how the motor reacts.

The Arduino Servo library generates the PWM signal that drives the servo. The frequency is 50 Hz.

002_full_signal.jpg


I'm using the test bed from the previous post to check the PWM across the range.


001_signal_start.png

I've entered full speed counterclockwise, half speed, stop, half speed clockwise and full speed.

The table below gives a capture of the high part of the PWM.


 

0: full speed counterclockwise003_00.jpg
45: half speed counterclockwise004_45.jpg
90: stand still005_90.jpg
135: half speed clockwise006_135.jpg
180: full speed clockwise *007_180_scale.jpg



* the scale of the 180 signal is different because the PWM is too wide to fit on the scope screen in the range used for the other measurements.



The Enchanted Objects kit includes a TinkerKit Servo Module.

That servo motor is not your common 180° angle adjustable unit. It's something special.

 

Photo 03-04-15 23 16 15.jpg

 

Digital Continuous Rotation (360°) Servo

 

It's a SM-S430R continuous rotation type (http://www.farnell.com/datasheets/1581465.pdf)

The continuous servo doesn't work like the common one.

If you connect it to an Arduino and run the Servo examples, you'll be amazed (that is: if your workbench survives it - I tested it with a long iron beam attached to it and the thing started hacking into my function generator).

 

On a common servo, you can call Servo.write() with a value between 0 and 180. The servo will move to a fixed position for each value between 0 and 180 and stop.

But for a continuous servo, this value determines the speed.

 

Servo.write(0) the motor spins counterclockwise as fast as it can - and keeps running

Servo.write(90) the motor grinds to a halt

Servo.write(180) the motor spins clockwise as fast as it can - and keeps running


A safe way to test the servo is with this minimal sketch. It will start spinning the turn the motor clockwise at a low speed, and runs at that speed forever.

Pin 9 is the Arduino control pin.

 

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

void setup()  {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(100);
}

void loop()  {
  // this space intentionally left blank
}




 

 

I've also made a test bed that allows you to control the motor via the serial monitor. When you enter a value between 0 and 180, the motor will run with that for 5 seconds. Then it stops.

Load to your Arduino,

 

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(90);
  Serial.println("Enter speed (0 - 180, 0 is fast left, 180 is fast right, 90 = stop)");
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {
    int iSpeed = Serial.parseInt();
    iSpeed = constrain(iSpeed, 0, 180);
    myservo.write(iSpeed);
    delay(5000);
    myservo.write(90);
    Serial.println("Enter speed (0 - 180, 0 is fast left, 180 is fast right, 90 = stop)");
  }
}



 

 

I'm still thinking how I can use this motor in my project. Because of its peculiar behavior, I'll have to come up with something that matches with this servo.

 

Click here for Part 2.

I received my kits today, Finally I can start with my first module of Enchanted Wardrobe. It would be around the Yun.

P.S the servo is quiet big, I got an idea to use it wisely ,IMG_2166.JPG@STAY TUNED! for more.

Thanks Element14 once again...

20150403.jpeg

 

We're entering a new chapter for the Perpetuum-Ebner turntable. The practical things are sorted out and the once defect table spins again.

Time for some enchantment. I'm going to build a light organ.

 

Digital Light Organ

 

There are a number of projects around that use an equalizer display chip to detect bass, mids and highs.

But I found one curious project on Cool Arduino that is fully digital. The Arduino light Organ uses FFT to detect low, mid and high.

There isn't a lot of coding needed - 11% program and 16% dynamic on a UNO - and it works excellent.

Here's a 10 seconds demo that shows how it reacts on a sweep of 20 Hz -> 20 kHz.

 

 

When you click on the link to the project above, you see a photo of an Elektor magazine, March 1982, Spanish version.

I have the Dutch edition of that same month lying around somewhere. I'll post a front cover scan if I manage to locate it.

 

The Program

 

In the setup, the ADC is configured for 38 kHz sampling, and the reference is set to the internal one. Grease up your Spanish and read further:

 

    // Configuramos el prescaler a 32 -> 16Mhz/32 = 500 KHz
    // como cada conversion son 13 ciclos 500/13 ~ 38.4KHz
    // Es decir podemos medir en teoria hasta unos 19KHz,
    // que para este proyecto sobra.
    bitWrite(ADCSRA,ADPS2,1);
    bitWrite(ADCSRA,ADPS1,0);
    bitWrite(ADCSRA,ADPS0,1);


    // Como la señal es muy baja,utilizamos la referencia interna
    // de 1.1 V en vez de la de defecto de 5 V.
    analogReference(INTERNAL);




 

In the loop, the code takes an array of samples, applies Hann windowing function, and then sends the result to the FFT library for processing.

The result is data on 64 bands across the range.

 

    // Realizamos el muestreo
    for( int i=0; i < MUESTRAS; i++) {
       data[i] = analogRead(0)/4 -128;  //Convertimos de 0..1024 a -128..127                             
       im[i] = 0;                       // parte imaginaria = 0                      
    }

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

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




 

The code splits that up in 3 bands, and does some smart stuff to make the LEDs work across a dynamic range of input strength.

The light organ functions well for silent and loud parts of sound. It adjusts its behavior.

Visit the Cool Arduino blog to see that part of the code. The article has an in-depth explanation of the flow from sound sample to flashing LEDs

 

Demo Signal

 

I used my function generator in sweep mode. It scans the audio band (the human band, not the dog audio band).

You can see the bass, mid and high LEDs switch on when the signal is in range.

 

sweep.jpg

 

My DC offset is a bit high here, 2.7 in stead of 2.5, and the amplitude is on the high side too.

But it's all in the safe range for the microcontroller.

Bass is active around 450 Hz, Mid approx 1400 Hz and High kicks in close to 9 kHz.

 

I'm going to check how I can turn this demo setup into an Infineon Led Shield powered show, and where I can mount the LEDs in the player for an enchanted look-and-feel.

 

There was supposed to be a video here with a walk-through, but the rendering takes a bit long today.

 

 

 

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

Last week I wanted to publish a flowchart of the process of building the enchanted typewriter. However, since I'm organizing an exciting event for next month, I've been quite busy and couldn't do it.

 

I have a bit of time now, so let's see the project roadmap. Since the design process is quite linear I decided to break it down into 4 phases, so that you can get a more clear view of the project development and to separate it into different time frames. The last phase is just a possibility and will not necessarily be included in the final project, since I don't know if I'll make it in time.

 

Here's a diagram of the development process:

 

Design_diagram_1.png

 

For starters, I will only use three colours (red,blue and green) because it's faster to debug than while using a ton of them and also for space reasons.

 

I still don't know if I should make the interpolation with javascript or python. I know how to do it in python, but doing it in javascript would also be nice. Does anyone know of any simple javascript library that could do the trick?

 

With this, if I only reach the third phase, the final project will look like this:

 

Working_diagram_1.png

 

 

However, if I can get to finish the fourth phase before the deadline, the project would have some interesting extra features:

 

Working_diagram_2.png

 

 

Feel free to point out any errors or doubts you have about the project. Suggestions are always welcome!

I made some modifications to the original circuit I talked about in my previous post and made it on a bread board. Here is the resulting circuit

 

05 - Heart beat sensor circuit.jpg

05 - Heart beat sensor circuit 2.jpg

 

I placed my finger on the sensor, and I got a quite clean signal

 

05 - Heart beat sensor signal.jpg

The signal is 200 mV peak-to-peak. Since the ADC has a 10 bits resolution over a 5V range, the signal will be read as 80 ADC steps, which should be enough to make heart beat detection easy

I've blogged about my first steps with the kit, Review 1: Unboxing and First Steps.

 

Photo 19-03-15 12 19 44.jpg

 

Since then, I've been trying to set up a tool chain that can build the SAMA5D4X Explained Software Package from source (yes, it took me 9 days to get to this stage - tough board to get started with).

 

eclipse.png

 

I tried several tool chains and approaches. I'm not going to elaborate on the things that I didn't get working.

Here is what works for me on a Windows 8.1 64 install.

 

The Source

 

I downloaded the library and example sources from SAMA5D4 Software Package. There's an archive there with the name SAMA5D4 GNU Software Package 1.2 for Xplained board.

There are 3 sections in the package:

  • documentation
  • library sources
  • application sources

The documentation folders describe the libraries and the example applications. There's also an additional text document there that describes how to port the examples to Eclipse.

examples.png

 

tip:
Don't place the sources deep in your directory structure.

I had to shorten the name of libraries\libboard_sama5d4x-Xplained\include\xdma_hardware_interface.h , and adapt the file libraries\libboard_sama5d4x-Xplained\board.h to reflect that name change.

 

The Compiler

 

I've installed GNU Tools for ARM Embedded Processors (version 4.9 2015q1). I used the Windows installer and accepted all defaults.

I followed the install instructions from GNU ARM Eclipse. The install menu contains good info. I paid proper attention to what options to switch off in the installation programs.

 

The IDE

I reuse the Eclipse Luna edition that is running on my PC (Luna Service Release 1 (4.4.1)).

abouteclipse.png

The tool chain is available in Eclipse straight away if you follow the instructions from GNU ARM Eclipse.

 

toolchain.png

 

 

The Additional Build Tools

 

It's a good time to test now if the build process works by following the instructions in documentation\MigrationFromCStoEclipse.

If you don't have a working make installation on your computer, these following steps may be necessary:

Again following the instructions from GNU ARM Eclipse, you install the  GNU Tools for ARM Embedded Processors.

If done right the build tool chain is available in Eclipse.

buildtools.png

 

 

This would be a good test again to see if you can build a library.

I couldn't. My builds were still failing after this install. See Who has successfully compiled a project of SAMA5D4 GNU Software Package 1.2 for Xplained board on Windows? for details on what was going wrong.

 

I had to additionally add this software package to get it working: GnuWin32.

I picked up this requirement from on Received the Atmel SAMA5D4 Xplained Ultra board! Yay! by  pettitda.

 

It becomes tricky here. Some of the tools appear in both additional build tools packages. You may have to be creative with the different path settings in Eclipse to make this all work.

 

 

With this setup, I could successfully build all libraries from source.

I haven't been able to build one of the examples and load it to the board. That's something for a next post.