Skip navigation
1 2 Previous Next

Arduino

16 Posts authored by: Jan Cumps Top Member

I thought I was finished with this road test, but the creative part of the brain refused to shut down. Here's my final throw at the [Christmas Wreath of Things] Internet of Holiday Lights - summary.


This is my tribute to Radio Shack / Tandy.

You pulled me into electronics. The imprint of my nose is probably still visible on the window of the shop that was once your store in Diest, Belgium.

A big thank you, and Fan Forever!



 

The road test is closing down. I had already submitted my final story. And then this idea materialized when I was updating a speaker picture to my Twitter series about the Radio Shack :

"Can I make the Yún shout out the names of my friends on element14?".

 

Turns out that I can (barely - I've stretched the memory of my Yún beyond believe).

Here's the article that got me on the rails: Is it possible to make Arduino talk without shield

 

My eldest daughter made an amplifier on the Science Fair 200 in One LAB (she isolated the amplifier part out of project 180 - octave generator)
while I was struggling to get the TSS library work on Ardiuino IDE 1.5.x and fitted it in the memory together with the MQTT lib.

She finished well before me.

Photo 20-01-15 21 01 27.jpg

 

Here's the result. You can hear the kit saying my name once, and peteroakes' name twice:

 

The video is a real capture of messages arriving. The speech you hear are real messages posted to the Eclipse IoT broker by fellow element14 members.

 

This is my final final entry. A big thank you to all: you know who you are. :like:

 

Some geek compliant pictures to close my campaign:

Photo 20-01-15 21 05 08.jpg Photo 20-01-15 21 03 29.jpg

Jan

The participants of the The Internet of Holiday Lights RoadTest Plus received these three devices:

  • Infineon Lighting RGB LED Arduino Shield
  • Arduino Yún
  • Arduino Uno

 

 

  • Evaluation Type:Evaluation Boards
  • Application you used the part in:[Christmas Wreath of Things] Internet of Holiday Lights - summary
  • Was everything in the box required?:Yes - complete
  • Comparable Products/Other parts you considered:There are plethora of other IoT capable development boards and RGB drivers
  • What were the biggest problems encountered?:USB connection to PC of the Arduino Yún

 

Scoring

Product Performed to Expectations:7
Specifications were sufficient to design with:10
Demo Software was of good quality:9
Demo was easy to use:7
Support materials were available:10
The price to performance ratio was good:10

TotalScore:53 / 60

 

Infineon Lighting RGB LED Arduino Shield

 

This board is tagged as an RGB driver shield. But it is actually a fully capable microcontroller all by itself.

The manual for the evaluation board says 'XMC1200 Microcontroller Series for Industrial Applications'.

And that's no lie. The board hosts an Infineon XMC1202. One of its peripherals is 'Brightness Color Control Unit (BCCU) for LED lighting control'.

 

When using it as an Arduino shield, your sketch talks to the controller using i2c.
But since the shield sports a debug header, you could just as well program the on-board controller.

shabaz has written about that in his RGB LED Shield from Infineon - Getting Started Guide.

 

Using the board is not difficult, but I think Infineon can do  a better job explaining the configuration parameters and the limits calculations.

It is all understandable if you read their documentation for the shield and inspect the schematics a few times.

A nice narrative explanation of the concepts wouldn't be bad though.

However, I give Infineon an A for the completeness of specifications and principles of LED driving operation - and the elaborate explanation of that part.

Several road testers have made a library for the board. Compare the Infineon RGB libraries that spawned from the Internet of Holiday Lights

 

A watch-out: the shield uses D14 and D15 for i2c.

This can be an issue when this board is stacked on other shields that don't have these two 'newer' pins (e.g.: some of SparkFun and Velleman shields).

I had to do some bodge-wiring in my design:

 

And a second watch-out. This board (at least my board) emits a high frequency pitch when driving the leds. The pitch changes depending on the intensity.

This can be annoying if you're using it in a silent place - and your dog may complain.


Arduino Yún

 

I'm not going to write down the capabilities of this board. I would only repeat what thousands of other reviewers have done before.

I'll just tell about my first experiences with the Yún.

 

Photo 17-01-15 17 59 12.jpg

 

I have skills in both Arduino development and Linux. So the only step I had to talke was to learn how to link the two worlds and how to get each of them connected to the PC.

 

Making the sketch world talk to the Linux world was so simple. I loaded the Bridge TimeCheck sketch, inspected it, and done.

It's all self-explanatory. Also the other interaction principles explained on arduino.cc Yún getting started page worked straight away.

Getting the Yún up and running and connecting it to my home WiFi was also easy. Follow instructions, and done. Works.

The same for telnetting into the Linux part. I used the instructions for Putty and was on the Linux prompt in minutes.

I've used the ATMega timer interrupts in my sketch. It worked well with calling the Linux part. So they really run beautifully in parallel.

 

The USB connectivity is another story. It's been playing up from the beginning that I installed the Yún and is continuing to be a * in the *.

Disclaimer: I have a recent PC, recent OS and the drivers all installed ok.

But at regular times, the Yún disappears from the radar. And it doesn't get re-listed when I unplug it and plug it in again.
Even rebooting the PC does not help. And I have pushed all possible reset buttons on the Yún to no avail.

 

The symptoms are these:

- the Yún is not visible in the IDE.

- there's no COM port assigned to a Yún

- the Yún appears as a problematic device in the device manager.

 

 

 

Fixing it requires one or two steps. I haven't figured out why it is sometimes one and sometimes two steps.

If I select the Choose Driver from the device manager, sometimes the Arduino Yun driver is listed.

In that case I select that driver, push next, and the Yún is back in the USB world.

Sometimes the Arduino Yun driver is not listed. Then I have to first select the standard Port driver first.

 

After that I can go back into the 'flagged device', and the Arduino Yun driver is available.

Upon re-selecting that, the Yun is USB-able again.

So yes, strange. May be related to my PC - but still, it's a normal recent one, and it happens.

 

And what's that with the USB and Ethernet connector position on the Yún? They interfere with almost every shield in existence.

Either the pins of your shield are to short. Or when they are long enough, the two metal connectors shortcut something on the underside of your shield. Why?

None of my shields I have at home fitted (SainSmart, Adafruit, Velleman, Infineon).

 

The internet of things talks

 

I drove the memory use of the Yún to red when I made a talking sketch.

I used the Yún to read out aloud the payload of messages I subscribed to .

Sketch uses 28,454 bytes (99%) of program storage space. Maximum is 28,672 bytes.

Global variables use 1,208 bytes (47%) of dynamic memory, leaving 1,352 bytes for local variables. Maximum is 2,560 bytes.

 

But it works. It took me 1 hour to adapt the TSS example to the Yún and latest IDE release, and 3 hours to bring the memory under the maximum.

Here you can hear the Yún shout out my name once, and peteroakes name twice.

The amplifier is a Science Fair 200 in One kit. That is my tribute to Radio Shack. A company that I care for a lot. Tandy: respect forever!

 

Early sketch (Works, there's a delay sometimes - but it can be a start point to get you going. You go and debug it please):

 

// needed for MQTT and Process lib
#include <Bridge.h>
// MQTT  includes start




#include <SPI.h>
#include <YunClient.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>




#include <TTS.h>
TTS text2speech;  // speech output is digital pin 10








YunClient c; // replace by a YunClient if running on a Yun
IPStack ipstack(c);
MQTT::Client<IPStack, Countdown> client = MQTT::Client<IPStack, Countdown>(ipstack);




bool messageChanged = false;


// start MQTT functionality ====================================




void mqttInit() {
//  Ethernet.begin(mac); // replace by Bridge.begin() if running on a Yun
  Bridge.begin();


  // // Serial.println("MQTT Internet of Holiday Lights example");
  connect();
} 


void messageArrived(MQTT::MessageData& md) // this handler is called when a subscribed MQTT message arrives
{
  MQTT::Message &message = md.message;
text2speech.say((char*)message.payload); //    Test_Speech();
  client.yield(1000);


}


void connect()  // connect to the MQTT broker
{
  ipstack.connect("iot.eclipse.org", 1883);

  // // Serial.println("MQTT connecting");
  MQTTPacket_connectData data = MQTTPacket_connectData_initializer;      
  data.MQTTVersion = 3;
  data.clientID.cstring = "1cfee8dd0afc_yun"; //(char*)_id;
  client.connect(data);
  client.subscribe("element14_IoT", MQTT::QOS1, messageArrived);  
}


void sendAliveMessage() {
  if (!client.isConnected())
    connect();

  MQTT::Message message;

  message.qos = MQTT::QOS1;
  message.retained = false;
  message.dup = false;
  message.payload = (void *)"jancumps"; //(void*)payLoadBuf;
  message.payloadlen = 8; // strlen(payLoadBuf)+1;
  client.publish("element14_IoT", message);
  client.yield(1000);
} 


// end MQTT functionality ==============================


/*
void Test_Speech() {
// text2speech.setPitch(6); //higher values = lower voice pitch
// strcpy(printbuf, "Hello  master! How are you doin?");
text2speech.say(printbuf);
/* delay(500);
text2speech.setPitch(1); //lower values = higher voice pitch
strcpy(text, "I am fine, thankyou.");
text2speech.say(text);*/

/*
}


*/


void setup()
{


//  Serial.begin(9600);
//  delay(10000); // give me time to start the yun monitor
  // MQTT related tasks
  mqttInit();
}


void loop()
{

  // non timer related functionality comes here
//  static unsigned int uCounter = 0;
sendAliveMessage();
delay(60000);


//  uCounter++;


}

 

 

 

Arduino UNO

 

The most reviewed gizmo in the world. I didn't use it in my final design.

It had prototyping duty.

All not-IoT related parts have been prototyped on the UNO when the Yún was already ripping away on the Internet of Things.

 

IMG_3990.JPG

XMAS is over

 

On January 6, we remove our Christmas tree and lights in Belgium. So it's also time for my Christmas Wreath of Things to switch off.

But we still have our Secret IoT Service going on - and I want to enjoy that for a little longer.

 

So I switched over to a low profile design: an LCD that glows when one of my Secret IoT Service partners is alive,

and shows the name of the last person that sent me an I'm alive message.

In the picture below, it was peteroakes.

 

Photo 08-01-15 12 12 32.jpg

 

What's happening?

 

If no one but me is on-line, the display is blank, and the backlight off.

Once I receive a message from one of my friends, the Thing wakes up:

It sets a seconds counter to 120 seconds, and remembers the name of the sender.

 

The display lights up, and shows who was broadcasting:

 

lcd.jpg

 

 

Left upper corner shows my countdown timer. Each second the timer decreases.

Right lower corner shows the sender (in this case fvan).

 

If I receive no new message within 120 seconds, the backlight switches off, the display is blanked

and we go back to sleep.

 

Code:

 

 

// needed for MQTT and Process lib
#include <Bridge.h>








// MQTT  includes start




#include <SPI.h>
#include <YunClient.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>


#include <string.h>
// MQTT includes end




// include the library code:
#include <LiquidCrystal.h>
#define PIN_LCDLIGHT 10




// start MQTT declarations
char printbuf[100];


YunClient c; // replace by a YunClient if running on a Yun
IPStack ipstack(c);
MQTT::Client<IPStack, Countdown> client = MQTT::Client<IPStack, Countdown>(ipstack);
char payLoadBuf[] = {'j', 'a', 'n', 'c', 'u', 'm', 'p', 's', 0};
const char* send_topic = "element14_IoT";
const char* subscribe_topic = "element14_IoT";
const char* _id = "1cfee8dd0afc_yun";
// end MQTT declarations




// start frederick declarations
unsigned int uFrederickIsAlive = 0;
// end frederick declarations


// initialize the library with the numbers of the interface pins
// LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);




char lastPayload[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};






// start timer functionality ============================================================
boolean bRunSeconds = false;
boolean bIsRunningSeconds = false;
boolean bRunMinutes = false;
boolean bIsRunningMinutes = false;
boolean bRunHours = false;
boolean bIsRunningHours = false;


void runSeconds() {
  bIsRunningSeconds = true;

  // // Serial.print("s"); // remove when confident


  // task: keep MQTT alive
  client.yield(30); // this takes 30 ms. May reduce the parameter // if you get duplicates, increase

  // task: handle frederick alive functionality
  // task: every minute; we take one live away from frederick
  if (uFrederickIsAlive) {
    uFrederickIsAlive--;
    sprintf(printbuf, "%3u%c", uFrederickIsAlive, 0);
    lcd.setCursor(0, 0);
    lcd.print(printbuf);
    lcd.setCursor(0, 1);
    lcd.print(lastPayload);
    pinMode(PIN_LCDLIGHT, INPUT);   // high impedance turns on light
  } else {
    pinMode(PIN_LCDLIGHT, OUTPUT);   // low impedance LOW turns off light
    sprintf(printbuf, "                %c", 0);
    lcd.setCursor(0, 0);
    lcd.print(printbuf);
    lcd.setCursor(0, 1);
    lcd.print(printbuf);
  }
  Serial.println(uFrederickIsAlive);



  bRunSeconds = false;
  bIsRunningSeconds = false;
}


void runMinutes() {
  bIsRunningMinutes = true;

  // // Serial.println("m"); // remove when confident

  // task: flag to Frederick that I'm alive
  sendAliveMessage();



  bRunMinutes = false;
  bIsRunningMinutes = false;
}


void runHours() {
  bIsRunningHours = true;

  // // Serial.println("h"); // remove when confident

  bRunHours = false;
  bIsRunningHours = false;
}


void timerInit() {
  // initialize timer1 for 1 second ticks; ISR(TIMER1_COMPA_vect) will be called as interrupt handler
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;


  OCR1A = 62500;            // compare match register 16MHz/256/1Hz
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();             // enable all interrupts
}


ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
{
  static unsigned int uSeconds = 0;
  uSeconds++; // every call is a second
  bRunSeconds = true; // so yes, flag that the seconds handler should be called
  bRunMinutes = ! (uSeconds % 60); // each 60th second, flag that the minutes handler should be called
  if (uSeconds > 3599) { // every hour
    bRunHours = true; // flag that the hours handler should be called
    uSeconds = 0; // and start over
  }
}


void timerTasks() {
  if (bRunSeconds && ! bIsRunningSeconds) { // timer interrupt flagged that seconds handler should be called
    runSeconds(); // but we only run it if it's not active
  }
  if (bRunMinutes && ! bIsRunningMinutes) { // timer interrupt flagged that minutes handler should be called
    runMinutes(); // but we only run it if it's not active
  }
  if (bRunHours && ! bIsRunningHours) { // timer interrupt flagged that hours handler should be called
    runHours(); // but we only run it if it's not active
  }
}


// end timer functionality =====================================




// start MQTT functionality ====================================




void mqttInit() {
//  Ethernet.begin(mac); // replace by Bridge.begin() if running on a Yun
  Bridge.begin();


  // // Serial.println("MQTT Internet of Holiday Lights example");
  connect();
}


void messageArrived(MQTT::MessageData& md) // this handler is called when a subscribed MQTT message arrives
{
  MQTT::Message &message = md.message;

  // debug code
  sprintf(printbuf, "Message arrived: qos %d, retained %d, dup %d, packetid %d\n",
  message.qos, message.retained, message.dup, message.id);
  Serial.print(printbuf);
  sprintf(printbuf, "Payload %s\n", (char*)message.payload);


  Serial.print(printbuf);

  /*
  // sprintf(printbuf, "Topic len %d\n", md.topicName.lenstring);
  int i;
  for (i = 0; i < (md.topicName.lenstring.len); i++) {
    printbuf[i] = md.topicName.lenstring.data[i];
  }
  printbuf[(md.topicName.lenstring.len)]=  '\n';
  printbuf[md.topicName.lenstring.len + 1]=  0;
  */
  int iPlCheck = strncmp(payLoadBuf, (char*)message.payload,8);

  if (iPlCheck) {
    Serial.print(printbuf);
    sprintf(lastPayload, "%16s", (char*)message.payload);
  
  
  
    uFrederickIsAlive = 120; // we give frederick two lives (minutes) to send an 'I am alive' live message.
  } else {
    Serial.println("it's my own message");
  }
}


void connect()  // connect to the MQTT broker
{
  char hostname[] = "iot.eclipse.org";
  int port = 1883;
  sprintf(printbuf, "Connecting to %s:%d\n", hostname, port);
  // // Serial.print(printbuf);
  int rc = ipstack.connect(hostname, port);
  if (rc != 1)
  {
    sprintf(printbuf, "rc from TCP connect is %d\n", rc);
    // // Serial.print(printbuf);
  }

  // // Serial.println("MQTT connecting");
  MQTTPacket_connectData data = MQTTPacket_connectData_initializer;     
  data.MQTTVersion = 3;
  data.clientID.cstring = (char*)_id;
  rc = client.connect(data);
  if (rc != 0)
  {
    sprintf(printbuf, "rc from MQTT connect is %d\n", rc);
    // // Serial.print(printbuf);
  }
  // // Serial.println("MQTT connected");

  rc = client.subscribe(subscribe_topic, MQTT::QOS1, messageArrived); 
  if (rc != 0)
  {
    sprintf(printbuf, "rc from MQTT subscribe is %d\n", rc);
    // // Serial.print(printbuf);
  }
  // // Serial.println("MQTT subscribed");
}


void sendAliveMessage() {
  if (!client.isConnected())
    connect();

  MQTT::Message message;



  char buf[100];
  int rc;
  // Send QoS 1 message
  // // Serial.println(payLoadBuf);
  message.qos = MQTT::QOS1;
  message.retained = false;
  message.dup = false;
  message.payload = (void*)payLoadBuf;
  message.payloadlen = strlen(payLoadBuf)+1;
  rc = client.publish(send_topic, message);
}


// end MQTT functionality ==============================


// start LCD functionality ===========================








void setupLCD() {

  pinMode(PIN_LCDLIGHT, OUTPUT);  //Set control pins to be outputs
  digitalWrite(PIN_LCDLIGHT, LOW);

  lcd.begin(16, 2);
//     lcd.setCursor(0, 0);
}


// end LCD functionality ===========================




void setup()
{


  Serial.begin(9600);
  delay(10000); // give me time to start the yun monitor


  // MQTT related tasks
  mqttInit();

  // initialise LCD
  setupLCD();


  // timer related tasks
  timerInit();
}


void loop()
{

  timerTasks();

  // non timer related functionality comes here





}


The idea

 

I've been dragging my feet to enter this contest.  Working with light is not my forte.

But The Internet of Holiday Lights RoadTest Plus has a creative component. And  that's what pulled me in.

I was going to build an Electro Mechanical Xmas Wreath of Things!

 

 

 

 

This is the proposal I submitted:

 

Christmas Wreath of Things

...  my entry is an electro-mechanical wreath.

...

The wreath is a combination of mechanics, electronics and internet connectivity.

For each advent week, there will be a light. above the light is a filter that hides all four lights initialy, and will reveal a light each Sunday, 'candle wreath style'.

 

 

Microcontrollers are used to motor-drive the optical filter. The internet will be used 'IoT compliant', to check what date it is, and reveal the correct number of lights based on that.

The wreath will work every year without user input. Plug it in and it will adjust itself to the right state of advent.

My aim is to give this either a K'Nex or steampunk look and feel.


image.jpg

 

In fact I don't know anything about te design yet. It's just an idea at this moment.

You'll find out together with me how it materializes.

 

At that time, I really didn't know much. As it turned out, the only thing I've left from the original idea was the dumb lights and motorized filter.

All other things changed during the build.

In this post I will not go into technical details. There's a list with all blog posts about this gizmo at the end of this post.

 

What did I come up with?

 

3degrees_orig.jpg

 

I like to challenge the nature of the exercise.

 

The focus was on lights. I came up with the idea to make the lights an intrinsic part of the design - but a downplayed part.

It would have been obvious to switch on one light for each Sunday in the advent.

I inverted that thought process: what if the lights are static, but something else makes them go on and off.

The mechanically driven optical filter does that  job.

advent01.jpg

The Infineon RGB shield can handle high power leds easily. So I used it to drive standard low power leds.
It's perfectly capable of doing that, but you're playing at the very low edge of its range. It's a tricky balance because you can easier overdrive standard leds than the sturdy high power ones.

The shield did an excellent job. Even though I did not put advent intelligence in the lights, I did animate them.

peteroakes's (I bet he'll be mentioned by some other participants too ) Infineon library was instrumental for a painless exercise.

 

IMG_3575.JPG

 

 

 

The Eclipse IoT. What's the use of the internet of things if you only talk to yourself?

fvan and I have our gizmos connected to each other.

Our devices act differently when we're both on-line. How novel is that?

 

 

Frederick's gizmoJan's gizmo
photo+1+%281%29.JPGgzmo.jpg

 

We think we've used the internet as it's supposed to be used. To interact with others.

And we've used it as 'things'. There's no human interaction. Both things are happy when the counterpart is live, and they show it!

 

iot01.jpg

 

The Arduinos. The Yún drives the whole thing. It's filled up with more than 90%. It has a very down-to-earth duty.

The UNO is doing a more creative job. I've given it as a present to one of my kids that helped me build the wreath.

Maybe one day she ...



What changed during the build?

 

I started with virtually no ideas. And even then almost everything changed.

 

  • I was going to use the internet to get the current date. I'm a novice to IoT - this is my first experience - and thought that it was all about using on-line services and functionality.

When I was setting up the Yún, I found out it has linux running - and has time sync functionality.

So I changed my mind, stepped away from searching for an on-line time service, and used that linux part to get at the right date - with localization support.

 

  • That also meant that I had to come up with something else for the IoT part. The work with Frederick more than filled that gap. It was a blast working together - you get the warm fuzzy when the gizmo lights up when you're not paying attention.

 

  • The mechanical part went through several changes.

I started with a light dc motor, but that was a bit hard to control. I didn't have many options to provide position feedback - let alone brake the fast but weak motor. Ditched it.

Idea two was a servo motor that I have lying around. It does the job better, but it was looking dull. I wanted gears and shiny copper.

In came the final solution: a stepper motor from a defunct flatbed scanner.

 

IMG_3980.JPG

I struggled somewhat with driving the motor - and wrote about that in the blogs listed at the bottom of the blog. It turned out to be a perfect solution.

As an added bonus, the stepper does not run very smooth. That adds to the look and feel of my design.

From the start, I wanted it to look scabby. I'm quite pleased with how it behaves:

 

 

  • I was going to build it alone. One of my kids came to the rescue when I was about to cut off my fingers during the arts&crafts part.

That may have been the part that I enjoyed most.

 

IMG_3543.png

 

Wrap up:

 

'twas fun! I'm glad I participated - and I learned a few new things along the way.

My design is not going to be the brightest light around here (total current used for leds: < 150 ma, all Arduino Yún  leds included ).

But it moves. And it communicates. It's alive!

All the best for 2015 !

 

 

My Blog Posts:

 

The posts in this table tell the whole story from beginning till completion. They are listed - and  written - in sequence, so you can follow along with me.

 

Blogs


My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.

In the fourth post I used the Linux part of the Yun to get at the current date and time.

In the fifth post I scavenged a stepper motor from a flatbed scanner.

In post six that motor was running.

Post seven is covering the Infineon RGB LED shield.

My post number eight is an aside on programming the advent calendar logic.

In post nine I'm covering the creative 'Arts & Crafts" part.

Post number 10 covers Time and Event handling,

and post 11 reveals the IoT conspiracy that Frederick and I prepped.

Post-Christmas design: [Christmas Wreath of Things] Internet of Holiday Lights : post Christmas blues

And the bonus kicker: [Christmas Wreath of Things] Internet of Holiday Lights - Bonus kicker: the IoT talks (a spoken tribute to Science Fair kits)

Comparing the Infineon arduino libraries from our element14 team.

The Official Road Test Review©.

Bonus material

 

Frederick's post on our shared design: [Christmas Tree] Internet of Holiday Lights - Special Feature

You can join in. Topics are shared on this thread: Internet of Holiday Lights:  Join the secret IoT Service - open for all

 

After January 6, I switched over to a post-Christmas design: [Christmas Wreath of Things] Internet of Holiday Lights : post Christmas blues

Photo 08-01-15 12 12 32.jpg

 

Bonus Bonus:

The Internet of Things shouts out the names of my fellow road testers:

 

 

 

 

A playlist of 11 videos I've uploaded during the work. Some made it to the blog posts.

 

 

and some photos:

 

backside.jpg dark.jpg frederick ster.jpg IMG_3424.JPG

 

IMG_3503.JPG IMG_3984.JPG IMG_3986.JPG

 

IMG_3987.JPG IMG_3990.JPG

 

IMG_4006.JPG Photo 23-12-14 23 28 16.jpg wreath0001.jpg

tandy.jpg

Several of us are posting a 'secret' message to the eclipse broker.

You can subscribe to our topics and share the Xmas Light of Things.

 

If you post your MQTT payload here, I'll add them to the list.

 

whopayload
fvanfvan
jancumpsjancumps
peteroakespeteroakes
mcb1mcb1

 

 

MQTT broker info:

host: iot.eclipse.org

port: 1883

please post a keep-alive every minute

QoS: 1

Topic: element14_IoT

The internet is supposed to be a forum for collaboration and sharing. And the Internet of Holiday Lights contest asks for creative use of Eclipse's IoT offering.

 

So the two Belgian guys (Frederick and me) decided to team up and use the internet as our platform to work together.
We believe that having our two devices connected to each other - and make them change each other's behavior - ticks the creative use of the Eclipse IoT offering box in an inventive way .

Our gizmos work in isolation. But only when both devices are online they show their full colors.

 

 

Frederick's gizmoJan's gizmo
photo 1 (1).JPGIMG_3999_L.JPG

 

 

What have we done?

 

Both Frederick (fvan on element14) and me have reserved part of our Thing's look-and-feel for shared functionality.

And both of us publish an I-AM-ALIVE message to the Eclipse IoT broker every minute. We both subscribe to each other's message.

When we receive a message from the other, we animate some part of our design. When there's no new 'I-AM-ALIVE' arriving within a given period, that animation stops.

You can't get more Christmas compliant than that - and we don't use the internet to talk to ourselves; we use it to enrich the experience.

 

 

How did we test it?

 

You can use the Eclipse Paho MQTT Utility to view traffic, but also to submit test messages. So I can simulate that Frederick's device is online by submitting 'his' message via Paho.

We also use it to monitor if the other gizmo is emitting messages. Ideal to see if our designs are actually reacting on the broadcast.

The screen capture below is me simulating Frederick's broadcast. So the messages are not coming from his device this time:

 

paho.jpg

 

Here's a capture of both gizmos broadcasting. It's our devices that are generating the messages:

messages.jpg

... and what's the effect?

 

The visual effect when our designs are on-line together:

 

Frederick's gizmoJan's Gizmo
photo 2 (1).JPG

 

So that's our creative Internet of Things offer:

"Use the internet to influence, communicate and work together. And use it to let our Thing be More Than a Thing"

Fun.

 

The gizmo design

 

I got a bottle of after-shave for New Year, and used the old bottle as a special effects light filter. I fitted two strings with a random number of green and red LEDSs in the bottle (It's the Infineon RGB shield's duty to manage the current - and it handles that responsibility very well).

In the front of the bottle I made a cut-out of part of one of Frederick's design drawings (the big star from his drawing below). I glued that drawing over the cut-out hole, and gently tapped the inner part of the star with olive-oil to improve the transparency.

frederick ster.jpg gzmo.jpg

 

Frederick's post: [Christmas Tree] Internet of Holiday Lights - Special Feature

 

Update

 

The IoT Team Up is open to all.

Internet of Holiday Lights: Join the secret IoT Service - open for all

 

We've published the details on how to share your heartbeats. A few members are preparing to add something in their design.

The result will be more exciting than what we envisioned at the start.

My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.

In the fourth post I used the Linux part of the Yun to get at the current date and time.

In the fifth post I scavenged a stepper motor from a flatbed scanner.

In post six that motor was running.

Post seven is covering the Infineon RGB LED shield.

My post number eight is an aside on programming the advent calendar logic.

In post nine I'm covering the creative 'Arts & Crafts" part.


This time I'll cover Time and Event handling.


Why Time management


My wreath will be doing several things. A few of them event handled, other repetitive.

  • There are some animations happening (LEDs dimming and flashing)
  • A connection with the Eclipse MQTT broker needs to be kept alive.
  • I'm sending MQTT messages to something for surprise functionality on a regular base.
  • Others.

 

I can handle all of this in the loop() function without real issues (it's not that complex after all). But a timer can handle all of this without me having to worry about it too much.

The ATMega has spare timers, so why not.

 

In my design I need three granularities:

  • things to be done approx each second
  • actions that should be done each minute
  • hourly activities

 

timeandevent0001.jpg

 

So I've set up a counter that ticks every second and manages the cadence.

void timerInit() {
  // initialize timer1 for 1 second ticks; ISR(TIMER1_COMPA_vect) will be called as interrupt handler
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;


  OCR1A = 62500;            // compare match register 16MHz/256/1Hz
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();             // enable all interrupts
}




 

 

My interrupt handler does nothing more than marking what jobs need to execute:

ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
{
  static unsigned int uSeconds = 0;
  uSeconds++; // every call is a second
  bRunSeconds = true; // so yes, flag that the seconds handler should be called
  bRunMinutes = ! (uSeconds % 60); // each 60th second, flag that the minutes handler should be called
  if (uSeconds > 3599) { // every hour
    bRunHours = true; // flag that the hours handler should be called
    uSeconds = 0; // and start over
  }
}




This is a very short routine that is guaranteed to give back control to non-interrupt code fast

 

I have a function that calls the right schedule at the right times. That function is the first call in my 'arduino sketch' loop():

void loop()
{

  timerTasks();

  // non timer related functionality comes here
  // ...




 

void timerTasks() {
  if (bRunSeconds && ! bIsRunningSeconds) { // timer interrupt flagged that seconds handler should be called
    runSeconds(); // but we only run it if it's not active
  }
  if (bRunMinutes && ! bIsRunningMinutes) { // timer interrupt flagged that minutes handler should be called
    runMinutes(); // but we only run it if it's not active
  }
  if (bRunHours && ! bIsRunningHours) { // timer interrupt flagged that hours handler should be called
    runHours(); // but we only run it if it's not active
  }
}




 

As an example, here's some household variables, runSeconds() and the beginning of runMinutes():

boolean bRunSeconds = false;
boolean bIsRunningSeconds = false;
boolean bRunMinutes = false;
boolean bIsRunningMinutes = false;
boolean bRunHours = false;
boolean bIsRunningHours = false;


void runSeconds() {
  bIsRunningSeconds = true;

  Serial.print("s"); // remove when confident


  // task: keep MQTT alive
  client.yield(30); // this takes 30 ms. May reduce the parameter // if you get duplicates, increase

// surprise functionality removed

  bRunSeconds = false;
  bIsRunningSeconds = false;
}


void runMinutes() {
  bIsRunningMinutes = true;

  Serial.println("m"); // remove when confident

  // ..




 

Why Event management


MQTT is event driven for the receiving side. You subscribe to a message, and provide the callback function that will be invoked upon incoming messages.

That is currently the only (non-interrupt) event driven scenario in my design.

 

timeandevent0002.jpg

Here's my handler. Some functionality that I'll reveal later is removed.

 

void messageArrived(MQTT::MessageData& md) // this handler is called when a subscribed MQTT message arrives
{
  MQTT::Message &message = md.message;

  // debug code
  sprintf(printbuf, "Message arrived: qos %d, retained %d, dup %d, packetid %d\n",
  message.qos, message.retained, message.dup, message.id);
  Serial.print(printbuf);
  sprintf(printbuf, "Payload %s\n", (char*)message.payload);
  Serial.print(printbuf);
  // end debug code



  // in the real world, I should validate if this is the right topic -- I've only subscribed to one so I'll not bother

  // here be secret codes for surprise functionality

}




 

Other candidates?


I may add an interrupt handler for a button that I plan to use, but since that is only to be used in calibration scenario's, I may just handle that in my loop(). I'm not in the mood to pull out my debounce lib.

I would go full-fledged if I had a keyboard or an end-user button interface. But that's not the case, so a simple check of the pin state in my loop will do.

 

update: execution log of one hour operation

invoking linux date
linux date invoked
20141231


20141231
day: 20141231 checking against: 20141130 checking against: 20141201 checking against: 20141202 checking against: 20141203 checking against: 20141204 checking against: 20141205 checking against: 20141206 checking against: 20141207 checking against: 20141208 checking against: 20141209 checking against: 20141210 checking against: 20141211 checking against: 20141212 checking against: 20141213 checking against: 20141214 checking against: 20141215 checking against: 20141216 checking against: 20141217 checking against: 20141218 checking against: 20141219 checking against: 20141220 checking against: 20141221 checking against: 20141222 checking against: 20141223 checking against: 20141224 checking against: 20141225 checking against: 20141226 checking against: 20141227 checking against: 20141228 checking against: 20141229 checking against: 20141230 checking against: 20141231 found state : 22
0
...
0
Payload secret
119
...
116
motor adjust in seconds: 9
115
motor adjust in seconds: 9
114
motor adjust in seconds: 9
113
motor adjust in seconds: 9
112
motor adjust in seconds: 8
111
motor adjust in seconds: 7
110
motor adjust in seconds: 6
109
motor adjust in seconds: 5
108
motor adjust in seconds: 4
107
motor adjust in seconds: 3
106
motor adjust in seconds: 2
105
motor adjust in seconds: 1
104
motor adjust in seconds: 0
103
motor adjust to advent state
102
...
65
m
64
...
6
5
m
4
3
2
1
0
0
...
0
Payload secret
119
...
106
motor adjust in seconds: 9
105
motor adjust in seconds: 8
104
motor adjust in seconds: 7
103
motor adjust in seconds: 6
102
motor adjust in seconds: 5
101
motor adjust in seconds: 4
100
motor adjust in seconds: 3
99
motor adjust in seconds: 2
98
motor adjust in seconds: 1
97
motor adjust in seconds: 0
96
motor adjust to advent state
95
m
94
93
...
36
35
m
34
33
...
4
3
2
1
0
0
...
0
0
m
0
...
0
m
h
invoking linux date
linux date invoked
20141231


20141231
day: 20141231 checking against: 20141130 checking against: 20141201 checking against: 20141202 checking against: 20141203 checking against: 20141204 checking against: 20141205 checking against: 20141206 checking against: 20141207 checking against: 20141208 checking against: 20141209 checking against: 20141210 checking against: 20141211 checking against: 20141212 checking against: 20141213 checking against: 20141214 checking against: 20141215 checking against: 20141216 checking against: 20141217 checking against: 20141218 checking against: 20141219 checking against: 20141220 checking against: 20141221 checking against: 20141222 checking against: 20141223 checking against: 20141224 checking against: 20141225 checking against: 20141226 checking against: 20141227 checking against: 20141228 checking against: 20141229 checking against: 20141230 checking against: 20141231 found state : 22
0
0
...


 

 

 

 

 


My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.

In the fourth post I used the Linux part of the Yun to get at the current date and time.

In the fifth post I scavenged a stepper motor from a flatbed scanner.

In post six that motor was running.

Post seven is covering the Infineon RGB LED shield.

My post number eight is an aside on programming the advent calendar logic.


This time I'm covering the creative 'Arts & Crafts" part.



Building the wreath


One of my kids helped me (read: did virtually everything) to build the wreath. We used only simple techniques.
The first task was to draw the top and bottom layer on a piece of paper.

wreath0001.jpg

 

wreath0002.jpg

 

We then transferred these drawings onto thick carton. We used a fat pencil to color the backside of both drawings black, taped the paper on the carton and traced the cut lines.

 

backside.jpg

That transfers the lines to the carton

calculeer.jpg

Next actions were to dremel out the two layers...

dremel.jpg

... and to decorate them

IMG_3547.JPG

 

Then it was back over to me, to add leds and motor, and to assemble the wreath.

IMG_3550.JPG IMG_3552.JPG

IMG_3565.JPG

 

Now the only two things left are writing the firmware and building the secret IoT part...

My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

I am now working on the software part of the 'advent state' logic.

 

In my design, there is a bottom layer (the wreath) with 4 lights that represent advent candles. They are always on.

On top of that, I'm mounting a circle with holes (the 'light filter').  That filter can turn and is driven by a motor.

 

 

Depending on what week of the advent we are, one, two, three or all four of the candles have to be shown.

There are 23 states:

  • state 0: not an advent date
  • state 1: first Sunday of advent, show one candle
  • state 2: first Monday of the advent, still show one candle
  • ...
  • state 8: second Sunday of the advent, show two candles
  • ...
  • state 15: third Sunday, show three candles
  • ...
  • state 22: fourth Sunday of the advent, and any day thereafter until January 6, show four candles

 

 

So I need logic to convert the day of advent into a particular position of the filter.

In one of my official posts on this contest, I have discussed my solution to get that date from the Yun's linux part.

And in that post, I was talking about intelligent solutions that would calculate the state for that day with nifty algorithms.

 

But now that I'm really implementing the solution, on a Sunday night after 12, the brain doesn't want to play along. So I resorted to a cheeky implementation:

  • I've hard-coded an array with advent days for the years 2014 and 2015
  • I've provided a second array with the corresponding states for each day in the advent
  • A lookup function that finds the correct state for any date within the covered period (let's call it the commercial guarantee period)
  • A function that looks up the day in linux and converts it to a long, in its own dodgy way

 

Below is the code. If you're looking for good code practices, this would be the right time to avert the eyes.

 



// includes for advent intelligence
#include <Process.h>


// ================================ START ADVENT CALENDAR SECTION ===========================================================


/* 
Advent intelligence


There are 23 states in my advent interpretation:
0: no advent
1: 1st sunday
2: 1st monday
...
8: 2nd sunday
...
15: 3rd sunday
22: 4rd sunday and any date between 25/12 and 6/1
For days between 25/12 and 6/1, state = 22 (same as 4rd advent Sunday


I have written the code this way to annoy you
to avoid any brain effort from my side, I have listed all dates from the first Sunday until January 6 in an array, 
and the corresponding advent states in a second array. If you find the day, you can look up the advent state.
For days not found in the list, state = 0


The date is presented as a long, just a conversion of the string YYYYMMDD converted to numerical. 
e.g.: date string "20141229" becomes long 20141229. Go figure :)


*/


// array with the advent intelligence lookup keys
long adventIntelligenceKey[] = {
// 2014
20141130, 20141201, 20141202, 20141203, 20141204, 20141205, 20141206, 20141207, 20141208, 20141209, 
20141210, 20141211, 20141212, 20141213, 20141214, 20141215, 20141216, 20141217, 20141218, 20141219, 
20141220, 20141221, 20141222, 20141223, 20141224, 20141225, 20141226, 20141227, 20141228, 20141229,
20141230, 20141231, 20150101, 20150102, 20150103, 20150104, 20150105, 20150106,
// 2015
20151129, 20151130, 20151201, 20151202, 20151203, 20151204, 20151205, 20151206, 20151207, 20151208,
20151209, 20151210, 20151211, 20151212, 20151213, 20151214, 20151215, 20151216, 20151217, 20151218, 
20151219, 20151220, 20151221, 20151222, 20151223, 20151224, 20151225, 20151226, 20151227, 20151228, 
20151229, 20151230, 20151231, 20160101, 20160102, 20160103, 20160104, 20160105, 20160106
};


// array with the corrsponding advent intelligence state
int adventIntelligenceValue[] = {
// 2014
  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 
22, 22, 22, 22, 22, 22, 22, 22,
// 2015
 1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22
};


/*
long getSysDate()
this function asks the Yun's linux part for the sysdate,a nd translates that to a long
retval: long - The current date as configured on the lini distro, just a conversion of the string YYYYMMDD converted to numerical
*/


long getSysDate() {
  long lRetval = 0L;
  Process date;                 // process used to get the date
  Serial.println("invoking linux date");
  if (!date.running())  {
    date.begin("date");
    date.addParameter("+%Y%m%d");
    date.run();
  }
  Serial.println("linux date invoked");
  while (date.available()>0) {
//    lRetval = date.readString().toFloat();    
    String timeString = date.readString();    
    Serial.println(timeString);


    lRetval = timeString.substring(0, 4).toInt() * 10000;
    lRetval += timeString.substring(4, 6).toInt() * 100;
    lRetval += timeString.substring(6, 8).toInt();
  }
  Serial.println(lRetval);

  return lRetval;
}


/*
int getAdventState(long day)
this function looks up the state of the advent. See comment section "Advent intelligence" above for the different states.
If the day passed to this function is found in the array adventIntelligenceKey, the corresponding state in array adventIntelligenceValue is returned.
Else we assume that we are not in the advent, and we return state 0.
The commercial guarantee of the gizmo powered by this algorithm should expire at the latest at the last day represented in the array above.
param day: the Long representation of a day to process, just a conversion of the string YYYYMMDD converted to numerical
retval: long - The current date as configured on the lini distro, just a conversion of the string YYYYMMDD converted to numerical
*/
int getAdventState (long day) {
  int i;
  int iRetval = 0;
  
  Serial.print ("day: ");
  Serial.print(day);
  for (i = 0; i < (sizeof(adventIntelligenceKey) / sizeof(adventIntelligenceKey[0])); i++) {
    Serial.print (" checking against: ");
    Serial.print (adventIntelligenceKey[i]);
    if (day == adventIntelligenceKey[i]) {
        iRetval = adventIntelligenceValue[i];
    Serial.print (" found state");
    break;
    }
  }
  Serial.print (" : ");
  Serial.println (iRetval);
  return iRetval; 
}


// ================================ END ADVENT CALENDAR SECTION ===========================================================




void setup() {
  // general setup
  Serial.begin(9600);    // initialize serial  
  
  // advent intelligence setup
  // the advent logic uses the lini part of the Yun, so Bridge needs to be initialised
  Bridge.begin();        // initialize Bridge
  
  // init motor
  
  // init leds
  
}


void loop() {
  
  int iState;


  // get date
  // get advent state
  
  iState = getAdventState(getSysDate());
  delay(10000); // TODO : remove debug code
  
  // adjust to advent state
  
  
  // do secret logic with MQTT


}

 

So all high standards have been thrown out of the door, but the code works:

 

adventlogic.jpg

My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.

In the fourth post I used the Linux part of the Yun to get at the current date and time.

In the fifth post I scavenged a stepper motor from a flatbed scanner.

In post six I got that motor working using a Velleman motor driver.


I am now adding the Infineon LED shield to the design. That finishes off the electronics part of my design.

 

IMG_3516.JPG


Theft


I blatantly stole peteroakes BYOB Party #3, Infineon Library Available. I've seen in the comments on the Internet of Holiday Lights blogs that I won't be the only one running away with it. Works perfectly, Peter!

So I won't elaborate on the software part here. Check Peter's blog post.


I didn't have stacking headers available. And normal mail headers do not leave enough spece between the shields. Using them would very likely create short circuits or other mishaps.

I decided to take another approach. I soldered female headers upside down on the bottom side of the Infineon shield, and used prepped' male headers to match the female headers of the two chields.

'Prepped' means that I forced the plastic part of the male headers to the center of the pins, so that there's enough pin left on both sides to make contacts with the female headers:

IMG_3510.JPG


stacker.jpg


Electronics prototyping finished


Now that I have all parts of the software solution tried out (I also tested the IoT MQTT library and got that working though I didn't blog about that [yet?]), I'm done with the investigating cycle.

The four main electronics functions of my design are covered:

  • I can drive a motor with sufficient precision, needed to get the light filter in the correct position.
  • I can talk to the linux part to get the current date for my timezone. I need that to know where I am in the advent cycle.
  • I can drive the Infineon shield to handle the lights part
  • I'm able to use the Eclipse IoT services for surprise functionality that I'm not going to reveal yet.


I've also tested the two most hardware dependent parts in combination: the stepper motor shield and the Infineon RGB driver shield. That worked out ok.



Here's the code of a combined stepper/led exercise:


// led shield includes
#include <Wire.h>
#include "Infineon.h"
// stepper shield includes
#include <Stepper.h>


// stepper constants
#define STEPA 4
#define STEPB 12
#define ENAA 5
#define ENAB 10
const int stepsPerRevolution = 96;

Infineon RGBLEDS = Infineon();


Stepper myStepper(stepsPerRevolution, STEPA, STEPB);



void setup() {              


    Serial.begin(9600);


    // led shield
    Wire.begin();
    Serial.println("buy time to start the serial monitor...");
    delay(5000); // wait 5s
    Serial.println("polling led shield...");
    while (RGBLEDS.on != 1) // Wait for shield to respond, keep setting the values till it does
    {
    
      Serial.println("led shield setup");


      RGBLEDS.I2CWRITE2BYTES (ADDRESS, FADERATE, 0x0000); // Immediate fade
      Serial.println("faderate set up");
      RGBLEDS.I2CWRITE2BYTES (ADDRESS, DIMMINGLEVEL, 0x0000); // 0% brightness level
      RGBLEDS.on = RGBLEDS.I2CREAD(ADDRESS, READ_DIMMINGLEVEL); // Request for brightness level
      if (RGBLEDS.message == 1 && RGBLEDS.on == 0) // If message received and dimming level = 0%, "message" is set in the I2CREAD function
      {
        Serial.println("message check for 0");
        RGBLEDS.message = 0;
        RGBLEDS.on = 1; // break out of loop
      }
    }
    RGBLEDS.I2CWRITE2BYTES (ADDRESS, OFFTIME_RED, 0x38); // Set off-time of red channel to 0x38
    RGBLEDS.I2CWRITE2BYTES (ADDRESS, OFFTIME_GREEN, 0x38); // Set off-time of green channel to 0x39
    RGBLEDS.I2CWRITE2BYTES (ADDRESS, OFFTIME_BLUE, 0x38); // Set off-time of blue channel to 0x38
    RGBLEDS.I2CWRITE6BYTES (ADDRESS, CURRENT_RGB, 0x80, 0x05, 0x05); // max:  0x80 = 780mA
    RGBLEDS.I2CWRITE2BYTES (ADDRESS, FADERATE, 0x0000); // Fade Rate between intensities --> 0.0s
    RGBLEDS.I2CWRITE2BYTES (ADDRESS, WALKTIME, 0x0000); // walk time between colors = 0s
    RGBLEDS.I2CWRITE6BYTES (ADDRESS, INTENSITY_RGB, 0x0555, 0x0555, 0x0555); // low level White Light
    RGBLEDS.I2CWRITE2BYTES (ADDRESS, DIMMINGLEVEL, 0x0FFF); // Maximum dimming level means inensity settings are directly used
  
    // stepper shield
  pinMode(ENAA, OUTPUT);  //Set control pins to be outputs
  pinMode(ENAB, OUTPUT);
  digitalWrite(ENAA, LOW);
  digitalWrite(ENAB, LOW);
  // set the speed at 30 rpm:
  myStepper.setSpeed(30);



}

  // the loop routine runs over and over again forever:
  void loop() {
    Serial.println("colour loop...");
    // change lamp colour to red
    RGBLEDS.I2CWRITE6BYTES(ADDRESS, INTENSITY_RGB, 0x0, 0x0, 0x0); // all off
    delay(500); // wait 1000ms
    step(stepsPerRevolution);
    // change lamp colour to green
    RGBLEDS.I2CWRITE6BYTES(ADDRESS, INTENSITY_RGB, 0x03ff, 0x03FF, 0x03FF); // 25%
    delay(500);
    step(-stepsPerRevolution);
    // change lamp colour to blue
    RGBLEDS.I2CWRITE6BYTES(ADDRESS, INTENSITY_RGB, 0x07ff, 0x07ff, 0x07ff); // Blue
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.I2CWRITE6BYTES(ADDRESS, INTENSITY_RGB, 0x0bff, 0x0bff, 0x0bff); // Blue
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.I2CWRITE6BYTES(ADDRESS, INTENSITY_RGB, 0x0fff, 0x0fff, 0x0fff); // Blue
    delay(500);
    step(stepsPerRevolution);
  // White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Aqua, Teal, Blue, Navy, Fuchsia, Purple
    RGBLEDS.SETCOLOUR( White);
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Silver );
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Gray );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Black );
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Red );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Maroon );
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Yellow );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Olive );
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Lime );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Green );
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Aqua );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR( Teal);
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Blue );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Navy );
    delay(500);
    step(stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Fuchsia );
    delay(500);
    step(-stepsPerRevolution);
    RGBLEDS.SETCOLOUR(Purple );
    delay(500);
    step(stepsPerRevolution);

  }



void step(int steps) {
    digitalWrite(ENAA, HIGH);
    digitalWrite(ENAB, HIGH);
    myStepper.step(steps);
    digitalWrite(ENAA, LOW);
    digitalWrite(ENAB, LOW); 
  }









My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.

In the fourth post I used the Linux part of the Yun to get at the current date and time.

In the fifth post I scavenged a stepper motor from a flatbed scanner.


I have that motor working now.






The motor driver kit

In my previous post I blogged about driving the motor with a 4 transistor H-bridge, and how I goofed that up. So I ended up dragging home a Velleman MOTOR & POWER SHIELD VOOR ARDUINO.

That shield's design is very similar to the Arduino Circuit for Bipolar Stepper Motor (the two pins example). Here's the two schematics side by side:

bipolar_stepper_two_pins2.png  velleman.jpg


Velleman and myself have one particular thing in common. We're both from Belgium.
The last time I've built a kit from them must have been somewhere in the late 80's. So I was quite excited to spend an evening of my Christmas holidays building up the kit.
There was one unpleasant thingy though. The smd ic was packaged in bubble wrap with tape around it. And someone in the kit assembly department must have been too strong for that job:

IMG_3489.JPG

No real harm done, I could straighten the pins without too much effort. Still, I'm expecting better...


Building the kit


That was not too difficult. There's only one smd component. In stead of soldering it with a fine tip pin by pin at the end - as advised by Velleman - I put that one up first.

I used solder paste and hot air. At my age, your eyes are happy that the don't have to stare at the 20 tiny pins while hand soldering each of them.

 

solder station

My solder station is an Aoyue 968A+. I've bought that with a voucher my company gave me earlier this year as a present. Because I'm a cheapskate, I searched for the lowest price (shipping included). That was on Amazon America.

The pleasant surprise came a week later when the Belgian tax authorities charged me an import tax that was lifting it way up above buying local. Go figure.

Photo 26-12-14 22 45 57.jpg

 

I'm rather fond on that solder station. Works well for me.


The other thing that I did different than Velleman's instructions is using flux. I'm soldering lead-free, and flux is more than welcome in that situation.
The kit is complete, and the instructions are easy to follow. And since it's been a while since I did that, it was quite an entertaining exercise.


IMG_3492.JPG



The software


I want to use the Arduino Stepper library. In this contest, one of my goals is to stick close to the nature of the devices.
IMG_3503.JPG


Since there isn't too much difference in design between Velleman's kit and Arduino's example, it shouldn't be too hard. And it isn't.

For the moment, I've left all the jumpers on my kit in their default position.

  • enable coil A on digital3
  • direction coil A on digital 2
  • enable coil B on digital 9
  • direction coil B on digital 8


I could use the Ardiono Shield example libraries with these changes:


in the constructor and setup(), I switched the output pins to reflect the jumpers on my shield, and enabled the enable (sic) pins.

#define STEPA 2
#define STEPB 8
#define ENAA 3
#define ENAB 9
#define BUTTON_CTRL 4
// ...
Stepper myStepper(stepsPerRevolution, STEPA, STEPB);


void setup() {
  pinMode(ENAA, OUTPUT);  //Set control pins to be outputs
  pinMode(ENAB, OUTPUT);
  digitalWrite(ENAA, LOW);
  digitalWrite(ENAB, LOW);
// ...
// set the speed at 60 rpm:
  myStepper.setSpeed(60);
   // initialize the serial port:
  Serial.begin(9600);

// ...








in the loop(), I took advantage of the enable capability of my shield:

void loop() {
  // step one revolution  in one direction:
// ...    
    Serial.println("clockwise");

    digitalWrite(ENAA, HIGH);
    digitalWrite(ENAB, HIGH);
    myStepper.step(100*stepsPerGearRevolution);  //  yes, I'm testing 100 full turns of the slowest wheel in my gearbox top test the resolution :) -- too lazy to count the cogs and ratios in my gearbox
    digitalWrite(ENAA, LOW);
    digitalWrite(ENAB, LOW);
    delay(500);
  }






I've successfuly tested the following examples on my stepper motor / shield combination:

examples.jpg

I haven't tried the other Stepper examples. I have no reason why they shouldn't work too.


Motor and gearbox resolution


I've measured the motor resolution by adapting the stepper_oneRevolution example.

I found info on my motor (the Neocene 2T3542146) on the manufacturer's site. The step angle is 3,75°. 3,75°per Step = 96 steps per rotation.

I have verified that by running this adapted example:

#include <Stepper.h>


const int stepsPerRevolution = 96;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 2);


int stepCount = 0;         // number of steps the motor has taken


void setup() {
  // initialize the serial port:
  Serial.begin(9600);
  pinMode(3, OUTPUT);  //Set control pins to be outputs
  pinMode(9, OUTPUT);
  digitalWrite(3, HIGH);
  digitalWrite(9, HIGH);

}


void loop() {
  // step one step:
  myStepper.step(1);
  Serial.print("steps:" );
  Serial.println(stepCount);
  stepCount++;
  delay(25);
}






To measure the full resolution, I marked one cog of the slowest gear in the reduction. Then I activated the motor and counted how many rotations of the motor where needed for one full rotation of that last gear in the reduction.

I came at approx 29.5 rotations.

Then I made the following sketch to fine tune. It waits for a button press and then takes what I think are the right amount of steps to make the slowest gear go around 100 times.

That should give me enough resolution to survive the advent weeks.



/*
Stepper Motor Control - one revolution


This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.


The motor should revolve one revolution in one direction, then
one revolution in the other direction.




Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe  (adapted by jc for the Internet of Holiday Lights - Velleman KA03 motor driver with Neocene 2T3542xmotor


*/


#include <Stepper.h>


#define STEPA 2
#define STEPB 8
#define ENAA 3
#define ENAB 9
#define BUTTON_CTRL 4




const int stepsPerRevolution = 96;


const int stepsPerGearRevolution = 30*stepsPerRevolution-32;  // change this to fit the number of steps per revolution


Stepper myStepper(stepsPerRevolution, STEPA, STEPB);


void setup() {
  pinMode(ENAA, OUTPUT);  //Set control pins to be outputs
  pinMode(ENAB, OUTPUT);
  digitalWrite(ENAA, LOW);
  digitalWrite(ENAB, LOW);


  pinMode(BUTTON_CTRL, INPUT);




  // set the speed at 30 rpm:
  myStepper.setSpeed(30);

  // initialize the serial port:
  Serial.begin(9600);
}


void loop() {
  // step one revolution  in one direction:
  if (! digitalRead(BUTTON_CTRL) ) {
    Serial.println("clockwise");
  //  myStepper.step(stepsPerRevolution);
    digitalWrite(ENAA, HIGH);
    digitalWrite(ENAB, HIGH);
    myStepper.step(100*stepsPerGearRevolution);
    digitalWrite(ENAA, LOW);
    digitalWrite(ENAB, LOW);
    delay(500);
  }

}




 

assorted scribbles:

DRIVER.jpg

My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.

In the fourth post I used the Linux part of the Yun to get at the current date and time.


I have now found a stepper motor to drive my wreath's optical filter.

Photo 23-12-14 23 28 16.jpg


The quest for a motor


I have a few dc motors in my scrap parts box,and a small servo motor. I 'm looking for something with a more mechanical look and feel. I want a gearbox in my design.

I opened an old car cassette player and a defect flatbed scanner.

F003_IMG_3460.JPG IMG_3466.JPG


Because I don't have the correct sized Torx driver, I couldn't get at the mechanism without getting medieval. I was more lucky with the scanner.

It 's easy to open (this one particularly because it has been dropped from a few stairs by one of my children a while ago).



I was able to get the motor out with the gear mechanism intact. It's a Neocene stepper motor. There's loads of info available on the internet on this motor and how to drive it.


Driving the stepper motor


I've been looking for several options. I could recover the driver chip from the scanner PCB, or build my own H-Bridge. I had just enough old school transistors available to build a prototype on breadboard.

hbridgeScan 1.jpg

The breadboarded example worked. I then decided to move the circuit over to the smallest protoboard I had available.

And that's when Murphy joined the party

IMG_3476.JPG


You can't see it because of the silkscreen, but this protoboard (the top one on the photo above) is not what it seems. Even though it looks similar to the one on the bottom, the top one has pads connected in groups of 3.
Of course, I didn't spot that while building up my circuit, so it only showed up when I was measuring the circuit before first power on.

The transistors were parts I had recovered from an old tape deck. The pins didn't survive my attempt to desolder them this time.

So I made a shopping list for new components (using European style transistors of the BD13X family).

hbridgeScan2.jpg

This morning I went to the local electronics shop (yes, open the day before xmas eve) with my list.

Turns out that they have a Velleman motor kit available.
The price difference between the kit and a set of loose components with stacking headers was not big.

So I decided to give myself a treat for xmas and bought my own presdent: the KA03 motor kit.

Photo 24-12-14 11 40 49.jpg



I was planning to use spare components as much as possible for the design, but I gave in this time. I'll be able to recover the motor driver for later use.
I'll spend part of my xmas holiday on building a Velleman kit. That's the first time since the mid-80's.

My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.

My third post was about getting the Arduino Yun up and running.


This time I'm making the Atmel and Linux part work together to get current date information.


datetimelinux.png


Because I'm changing the state of my gizmo based on the advent calendar, I need to know current date info.


Getting the right time from Linux


I've prepped my Arduino Yun to reflect the right date based on my timezone (Belgium).

timezone_1.png

timezone_2.png


Then I refreshed my knowledge of the Linux date command.

I need the following parameters to get the data I need for my design:

       %d     day of month (e.g, 01)


       %H     hour (00..23)


       %m     month (01..12)


       %M     minute (00..59)


       %u     day of week (1..7); 1 is Monday


       %Y     year





 

Command that I'll submit in Linux: date +%Y%m%d%u%H%M

Result: 2014122212306

 

I used the Arduino.cc Time Check example as a starting point to get all info into the sketch.

That wasn't too difficult. Here's the result:

 

datetimeyun.png

 


My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities.

In my second post I made a paper prototype.


This time I'm setting up the Arduino Yún.

There's an easter egg in this post.


IMG_3432.JPG


Software Setup


Well, that was easy. I already had Arduino IDE1.5.8 installed. The Yún requires 1.5.6 or higher, so that was ok.

The next package needed is Apple Bonjour. The IDE uses that to find the Arduino Yún on the wifi network. I simply installed it and didn't look into it any further.


Getting the Yún connected to the home wifi


That was simple too . I followed the arduino.cc instructions, and that worked for me without too much hassle.



Any hick-ups during the setup were due to my own mistakes. If you follow the guide step by step you should be good.

The only tests I've done at this moment are to load a sketch via wifi (worked!) and ssh/telnet into the linux shell (works too!).


PuTTY Setup

I have a PuTTY installed on my pc. That 'll do for the moment.
The arduino.cc instructions explain that you need to submit two commands in PuTTY to connect to the Yún, but it's simpler than that.

You just have to set the following settings and save them for later use, and you'll be fine:


Session:

Host name or IP address: <your Yún name>.local
Port: 22
Connection Type: SSH
Saved session name: Yún

pty1.jpg

Connection:Data:

Auto-login user name: root

pty2.jpg

go back to the Session category, and press Save.

pty3.jpg

You now have all the settings to get you connected via SSH and have a session into linux as root.

When you <Open> the session and enter the password on the linux prompt, you're in:

puttyshell_2a.jpg

 

This is another step for me to get closer to the Christmas Wreath of Things. I can't wait to start diving into the Eclipse IoT services...

My entry for the Internet of Holiday Lights is an electro-mechanical wreath.

My first blog post was a brain dump of possibilities. I'm a tiny step further now.

And I have received the ingredients.

 

IMG_3424.JPG

 

The paper prototype

 

Before diving into the electronics part, I want to have a tangible proto. Arts and crafts is not my forte, so don't expect too much.

I made a paper wreath and a paper filter gizzmo. It allows me to dry-run the mechanism.

 

What's next

 

I have no experience with the Yún. so that will be the first firmware topic that I'm planning to master.

I've watched Controlling Holiday Lights using MQTT and the Arduino Yún. I'll now try to follow the Yún tutorials first, learn the eclipse IoT solution,  and then make a service that knows what phase of advent I'm in.

 

Next is selecting an actuator for the filter. I've got a tiny dc motor and a servo motor. That will be the first things I'll turn to.

 

If the dc motor works best, I might need a position detector and brake mechanism. If I use the servo, the challenges will be more mechanical: how do I translate the limited movement into a circular movement.

 

I'll also see how I'm going to use the LED shield. My functional requirements for the shield are non-existing. That means I 'll have to find a creative purpose for the driver.

 

Photo 19-12-14 17 18 15.jpg

Filter Blog

By date: By tag: