element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Upcycle It
  • Challenges & Projects
  • Design Challenges
  • Upcycle It
  • More
  • Cancel
Upcycle It
Blog [Upcycle It] Interactive Race Car Driver - Controlling the Furby
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Workshopshed
  • Date Created: 24 May 2017 9:27 PM Date Created
  • Views 1401 views
  • Likes 7 likes
  • Comments 8 comments
  • upcycled_interactiveracecardriver
Related
Recommended

[Upcycle It] Interactive Race Car Driver - Controlling the Furby

Workshopshed
Workshopshed
24 May 2017

In the previous post, I looked at Hooking up the Furby to the Edison. Now to put that together with some software so we can control what the Furby does.

 

Motor

Driving the motor from the H-Bridge board is pretty much the same as per  [Upcycle It] Interactive Race Car Driver - Powering Motors although there are the extra transistor level shifters to factor in. This means all of the signals are inverted.

 

imageimage

MCU

As I discovered that the rate of pulses from the optical sensor is quite high, I decided that the MCU capability of the Edison would be ideal to monitor the inputs. Then a Node program can be used to get the current value of the counter from the MCU. So that the MCU knows which direction that the Furby's cam wheel is rotating a simple message can be sent over the serial communications channel.

image

Installing the MCU SDK

Installation of the SDK is straightforward, it's an Eclipse-based application so to get that to work on Windows there are quite a few extra components to install such as JRE and Cygwin.

 

I did have a few issues creating projects and this seemed partly due to my Workspace folder and partly because of my installation.

 

Ensure you:

  • Keep paths short
  • Keep paths without spaces in them
  • Install all of the components
  • Set the Environment variable

 

Installing the MCU SDK

 

Target IP

Unlike a lot of embedded SDKs the MCU SDK uploads the code over the network. So before you can upload your project you need to set the TARGET_IP. So I set that to the name of the board and it worked just fine.

image

For .local addresses to work on Windows, you might need to install a service such as Bonjour

 

https://learn.adafruit.com/bonjour-zeroconf-networking-for-windows-and-linux/overview

Sample Scripts

There are some tools that can help to configure the ports, it's worth downloading these as unlike things like MRAA, the MCU code "gpio_setup" does not actually configure the hardware to be an input or output.

 

Sample scripts for the MCU SDK

 

I installed the init_DIG script as follows:

 

mkdir tools
cd tools
wget http://downloadmirror.intel.com/24910/eng/init_DIG.sh
chmod +x init_DIG.sh
cd ..

 

Then configured a couple of the pins with:

 

./tools/init_DIG.sh -o 7 -d input
./tools/init_DIG.sh -o 8 -d input

 

This article Using an mcu on the intel edison board with the ultrasonic range sensor confirms that you need to do this each time the Edison boots. I'm also wondering if I can use MRAA to configure the ports in the control code for the Furby.

 

Testing

For initial testing, I used the grove shield, a switch for counting and capacitive sensor for reset.

 

The MCU application detects the signals with the aid of two interrupt handlers.

gpio_register_interrupt

Register an interrupt handler for one GPIO port.

int gpio_register_interrupt(int gpio, int mode, irq_handler_t isr);

...where:

  • gpio: GPIO port number
  • mode: 0 = falling edge interrupt, 1 = rising edge interrupt
  • isr: interrupt handler function
  • Return value: 0 if successful

The status is reported via the debug port and the current count can be received via the host to mcu serial port /dev/ttymcu0. I limited the counts to 50 for this initial testing to check it wrapped around correctly.

 

MCU Test code

#include "mcu_api.h"
#include "mcu_errno.h"
volatile int counter;
volatile int direction;
int maxPulses;
 int IRQpulse(int req)
 {
   counter += direction;
   if (counter < 0) {
    counter = maxPulses;
   }
   if (counter > maxPulses) {
    counter = 0;
   }
   debug_print(DBG_INFO, "Counter: %d\n",counter);
   return IRQ_HANDLED;
 }
 int IRQreset(int req)
 {
   counter = 0;
   debug_print(DBG_INFO, "Reset.\n");
   return IRQ_HANDLED;
 }
 void mcu_main()
 {
 char buf[64];
 char response[20];
    int retCode;
    int len;
    debug_print(DBG_INFO, "mcu app starting...\n");
    direction = 1;
    maxPulses = 50;    //Max pulses per revolution (need to find this experimentally)
    gpio_setup(48, 0);  /* set GPIO 48 DIG7 as input*/
    gpio_register_interrupt(48, 1, IRQpulse);
    gpio_setup(49, 0);  /* set GPIO 49 DIG8 as input*/
    gpio_register_interrupt(49, 1, IRQreset);
    while (1)
    {
     //Wait for command from host
     do {
      retCode = host_receive((unsigned char *)buf, 64);
         mcu_sleep(10);
     } while (retCode <= 0);
     switch(buf[0]) {
        case 'C'  :
         debug_print(DBG_INFO, "Counter: %d\n", counter);
         debug_print(DBG_INFO, "Direction: %d\n", direction);
         len = mcu_snprintf(response, 20, "C%d\n", counter);
         host_send((unsigned char*)response, len);
            break;
        case 'U'  :
        debug_print(DBG_INFO, "Up\n");
        direction = 1;
           break;
        case 'D'  :
        debug_print(DBG_INFO, "Down\n");
        direction = -1;
           break;
     }
    }
 }

 

I could not get Eclipse to display the debug log but from a console I could display it with:

 

cat /dev/ttymcu1 &

 

To interact with the MCU I used the 3 letters, C to display counter, D to count down and U to count up.

 

echo C > /dev/ttymcu0
echo D > /dev/ttymcu0
echo U > /dev/ttymcu0

 

image

The reset and pulse counters proved to work correctly. There are reports of the MCU not being able to cope with very high pulse rates. If this is the case I'll drop the debug statements and change the speed of the motor until it works reliably.

 

Monitoring the position

Once I was happy the MCU was working as expected I hooked the inputs upto the Furby. So that I could move both forward and backwards I needed to know the maximum number of pulses. To find this, I set the max in code to a large number and planned span the motor by hand.

 

Initially when I set this up the reset line was going wild. I used a resistor to pull that high and confirmed it worked by manually closing the contacts.

I manually span the slotted disk and after a short delay I got a reading of 209 pulses. Note to self, that needs to go to 1.8v when it's wired up to the mini-breakout.

 

I repeated this experiment with the motor driven from a battery and there was a debounce problem where I was getting multiple resets. Given that it was a mechanical spring contact this is not surprising. I added a simple delay into the reset interrupt handler and that improved the problem but did not completely eliminate the problem with a "bounce" appearing 7 or so pulses later. I'll likely use a mechanism where the reset initialtes a countdown and can't be retriggered until 10 or more pulses have been detected.

image

These experiments did provide repeated results of 208 pulses per revolution. I added that into the code and also added a call via the host API to return this max value. This experiment also demonstrated that the MCU was happily counting pulses and not obviously skipping.

 

Latest MCU code

#include "mcu_api.h"
#include "mcu_errno.h"
volatile int counter;
volatile int direction;
int maxPulses;
 int IRQpulse(int req)
 {
   counter += direction;
   if (counter < 0) {
    counter = maxPulses;
   }
   if (counter > maxPulses) {
    counter = 0;
   }
   debug_print(DBG_INFO, "Counter: %d\n",counter);
   return IRQ_HANDLED;
 }
 int IRQreset(int req)
 {
   counter = 0;
   mcu_sleep(20);  //Debounce
   debug_print(DBG_INFO, "Reset.\n");
   return IRQ_HANDLED;
 }
 void mcu_main()
 {
 char buf[64];
 char response[20];
    int retCode;
    int len;
    debug_print(DBG_INFO, "mcu app starting...\n");
    direction = 1;
    maxPulses = 208;    //Max pulses per revolution, was determined experimentally
    gpio_setup(48, 0);  /* set GPIO 48 DIG7 as input*/
    gpio_register_interrupt(48, 1, IRQpulse);
    gpio_setup(49, 0);  /* set GPIO 49 DIG8 as input*/
    gpio_register_interrupt(49, 1, IRQreset);
    while (1)
    {
     //Wait for command from host
     do {
      retCode = host_receive((unsigned char *)buf, 64);
         mcu_sleep(10);
     } while (retCode <= 0);
     switch(buf[0]) {
        case 'C'  :
         debug_print(DBG_INFO, "Counter: %d\n", counter);
         debug_print(DBG_INFO, "Direction: %d\n", direction);
         len = mcu_snprintf(response, 20, "C%d\n", counter);
         host_send((unsigned char*)response, len);
            break;
        case 'M'  :
         debug_print(DBG_INFO, "Max: %d\n", maxPulses);
         len = mcu_snprintf(response, 20, "M%d\n", maxPulses);
         host_send((unsigned char*)response, len);
            break;
        case 'U'  :
        debug_print(DBG_INFO, "Up\n");
        direction = 1;
           break;
        case 'D'  :
        debug_print(DBG_INFO, "Down\n");
        direction = -1;
           break;
     }
    }
 }

 

What next?

Test the H-Bridge with the mini-breakout and level shifters

Test the Sensors with the mini-breakout and level shifters

Write some high-level control code that communicates with the MCU and uses the counts from the Northwestern team to drive specific motions e.g. talking, ears waggling.

 

Reference

Installing the MCU SDK

Registering_an_interrupt_handler_to_a_GPIO_port

MCU API

Using an mcu on the intel edison board with the ultrasonic range sensor

Sample scripts for the MCU SDK

MCU interrupt performance

 

Previous Posts

Upcycle It Blogs tagged with upcycled_interactiveracecardriver

  • Sign in to reply

Top Comments

  • gpolder
    gpolder over 8 years ago +2
    nice update, thanks for explaining how to use the MCU.
  • Workshopshed
    Workshopshed over 8 years ago in reply to jasonwier92 +2
    Multiple events is why I dropped the delay approach. The frequency of events is slow enough for me to see in the console when the motor is turning at full speed. Let's say it's counting backwards and its…
  • jasonwier92
    jasonwier92 over 8 years ago +1
    How does your debouncing effect the counting frequency? OR what if the sensor gets two inputs, while you are still debouncing? Just to second what Gerrit Polder said, thank you for showing the MCU code…
Parents
  • gpolder
    gpolder over 8 years ago

    nice update, thanks for explaining how to use the MCU.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • gpolder
    gpolder over 8 years ago

    nice update, thanks for explaining how to use the MCU.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • Workshopshed
    Workshopshed over 8 years ago in reply to gpolder

    There are a few "gotchas" such as needing to setup the GPIO pins and remembering to build before you download but once you've got past those then coding for the MCU is pretty straight forward.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube