Search This Blog

Saturday, 18 April 2015

How we learned about electronics pre-Arduino days...

Very short post here: 

I was cleaning the basement, and came across this. It is "brand new", as in everything was still wrapped in it's original bubble wrap and had the cardboard corner protectors... huh... go figure..

Anyway boys and girls... this is what an Arduino looked like 20+ years ago.  LOL

130 rainy day electronics projects in one box...  

I tend to be a very forgetful person, but I *vividly* remember MY first computer.  

In 1976, Popular Electronics Magazine ran an article about building your very own personal computer.

The "Cosmac ELF was basically a PCB that you purchased, sourcing all of the electronic parts through the mail.  I think at the age of 10, it took me several months to get the components.  Sending off for one of two as my allowance came in, and soldering them to the circuit board. 

Picture from :
Using an 8bit RCA 1802 processor meant for the newly invented digital gas pumps, the Cosmac Elf boasted 256 bytes (BYTES!) of memory, two 7 segment LEDs, 8 toggle switches for address and data input, a RUN switch, and a PROGRAM switch.  

No BIOS or bootloader... nada... and yet some simple games could be loaded (in binary!) and played for hours of fun.

Two years later, I was up to 4k of memory, a cassette tape drive, and a monochrome video display of 128x64 bits...  and a home rolled character generator!

Those were the days...

I'd LOVE to hear your stories in the comments below...

Friday, 17 April 2015

PlatformIO - A Cross-Platform Code Builder and Missing Library Manager

I ran across this awesome site a couple weeks ago, and was astounded by their claims.  I had to try it out!

In a nutshell, PlatformIO has automated the various build aspects of cross compiling for your favorite Microcontroller across Mac OS X, Windows, and Linux, both on Intel as well as ARM (Meaning you can run PlatformIO on your Raspberry PI, or Beagle Board!)   

Basically, you can write your embedded code once, and compile across several target boards with very little additional work.

PlatformIO for each Operating system includes compiler, debugger, uploader (for embedded) and a bunch of useful tools. Popular settings for most popular Embedded Platform Boards are pre-configured out of the box.

To date, PlatformIO out-of-the-box support includes:

And of Special has worked with the guys that developed the Teensy 3.1 board to include it in their supported systems.  I make note of this, as the Teensy does use the Freescale Kinetis K20dx256 32bit ARM cortex-4 MCU, but they have simply made this board more readily available to work with.  (I also have a vested interest in this board!) 

Once installed, you can get a list of the 60 or more supported boards by typing “platformio boards” ...

 It's really as simple as installing PlatformIO onto your Laptop, Desktop, or Single board Computer (Raspberry Pi, BeagleBone, etc...), and choosing your target Embedded System to develop for. 

You Install PlatformIO itself, then invoke it to install the toolsets and libraries for your preferred board/processor,
something akin to  "platformio install freescalekinetis"  and it pulls down all of the cross compiler tools, and kinetis core libraries.

You then initiate a project with "platformio init -bteensy31".  It creates the directory structure, and you are free to use your favorite editor/IDE to write the code. 

No... this is not Visual Studio / Programming-with-your-mouse tool, but it DOES take care of a lot of the planning, configuration, build, and upload issues for you.

Once you have written your code, again invoking PlatformIO to build and upload is a simple process..  "platformio  run -t upload"... 

PlatformIO Library Manager allows you to organize external libraries. Searching for new libraries can be via commandline or Web Interfaces.  Python code in the background takes care of the rest.  Think of this as a package manager for your embedded libraries.

My fellow Teensy developers... If you feel constrained by the limitations of the  Arduino IDE (even though they did such an awesome job extending it with Teensyduino) And you are not up to the complexity of a full fledged bloated developer suite.. Please do yourself the favor, and try out PlatformIO.

Cross-board and cross-vendor embedded development with PlatformIO 
Discovered a new tool for embedded development: PlatformIO 
Integration of PlatformIO library manager to Arduino and Energia IDEs
Building and debugging Atmel AVR (Arduino-based) project using Eclipse IDE+PlatformIO

Wednesday, 8 April 2015

Marlin Firmware on Teensy 3.1 - Analog Temperature success!

I've successfully replaced the Analog functions in Marlin's temperature.cpp, with calls to Pedro Villanueva's ADC library for the Teensy 3.1, and am getting good temperature readings out of it.

Here's a couple shots from Repetier Host. 

Now on to updating the PID functions for the heaters...

This is looking quite doable my friends!

My Previous blogs on this project:
(little did I know I'd be working on this on and off for a year... and the real work is just beginning)

Monday, 6 April 2015

You have to see this Rich ADC library for Teensy 3.1 !!!

Several months ago, while working on my Robotic shield for the Teensy 3.1,  I had stumbled across this extremely rich and robust implementation of an ADC library, here  on the Teensy forum.
( )  Edit: updated as per author of library (15/04/06)

Written by a user of the Teensy, Pedro Villanueva started this library just over a year ago, but has implemented  most, if not all, functions of the Teensy 3.1 including use of both ADC available in the Teensy 3.1, as well as differential readings on the two built-in differential channels (A10-A11 and A12-A13).
Along with this library, he has written a simple ring buffer implementation which will prove quite handy.  There are also a number of very informative and well thought out examples.

List of methods of the library:
int ADC::analogRead ( uint8_t pin )
Returns the analog value of the pin.
It waits until the value is read and then returns the result. If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.

int ADC::analogReadContinuous ( )
Reads the analog value of a continuous conversion.
Set the continuous conversion with with analogStartContinuous(pin) or startContinuousDifferential(pinP, pinN)
Returns the last converted value.

int ADC::analogReadDifferential ( uint8_t pinP, uint8_t pinN )
Reads the differential analog value of two pins (pinP - pinN).
It waits until the value is read and then returns the result. If a comparison has been set up and fails, it will return ADC_ERROR_DIFF_VALUE.

void ADC::disableCompare ( )
Disable the compare function.

void ADC::disableDMA ( )
Disable ADC DMA request.

void ADC::disableInterrupts ( )
Disable interrupts.

void ADC::enableCompare ( int16_t compValue, int greaterThan )
Enable the compare function to a single value.
A conversion will be completed only when the ADC value is >= compValue (greaterThan=1) or < compValue (greaterThan=0) Call it after changing the resolution Use with interrupts or poll conversion completion with isADC_Complete()

void ADC::enableCompareRange ( int16_t lowerLimit, int16_t upperLimit,
int insideRange, int inclusive )

Enable the compare function to a range.
A conversion will be completed only when the ADC value is inside (insideRange=1) or outside (=0) the range given by (lowerLimit, upperLimit),including (inclusive=1) the limits or not (inclusive=0). See Table 31-78, p. 617 of the freescale manual. Call it after changing the resolution Use with interrupts or poll conversion completion with isComplete()

void ADC::enableDMA ( )
Enable DMA request.
An ADC DMA request will be raised when the conversion is completed (including hardware averages and if the comparison (if any) is true).

void ADC::enableInterrupts ( )
Enable interrupts.
An IRQ_ADC0 Interrupt will be raised when the conversion is completed (including hardware averages and if the comparison (if any) is true).

double ADC::getMaxValue ( )
Returns the maximum value for a measurement, that is: 2^resolution.

int ADC::getResolution ( )
Returns the resolution of the ADC.

int ADC::isComplete ( )
Is an ADC conversion ready?
Returns  1 if yes, 0 if not. When a value is read this function returns 0 until a new value exists So it only makes sense to call it before analogRead(), analogReadContinuous() or analogReadDifferential()

int ADC::isConverting ( )
Is the ADC converting at the moment?
Returns  1 if yes, 0 if not

void ADC::setAveraging ( unsigned int num )
Set the number of averages.
num can be 0, 4, 8, 16 or 32.

void ADC::setReference ( uint8_t type )
Set the voltage reference you prefer, default is vcc.

void ADC::setResolution ( unsigned int bits )
Change the resolution of the measurement.
bits is the number of bits of resolution. For single-ended measurements: 8, 10, 12 or 16 bits. For differential measurements: 9, 11, 13 or 16 bits. If you want something in between (11 bits single-ended for example) select the inmediate higher and shift the result one to the right.

void ADC::startContinuous ( uint8_t pin )
Starts continuous conversion on the pin.
It returns as soon as the ADC is set, use analogReadContinuous() to read the value.

void ADC::startContinuousDifferential ( uint8_t pinP, uint8_t pinN )
Starts continuous conversion between the pins (pinP-pinN).
It returns as soon as the ADC is set, use analogReadContinuous() to read the value.

void ADC::stopContinuous ( )
Stops continuous conversion.

int ADC::startSingleRead(uint8_t pin)
Starts an analog measurement on the pin and enables interrupts. It returns inmediately, get value with readSingle(). If the pin is incorrect it returns ADC_ERROR_VALUE This function is interrupt safe. The ADC interrupt will restore the adc to its previous settings and restart the adc if it stopped a measurement. If you modify the adc_isr then this won't happen.

int ADC::startSingleDifferential(uint8_t pinP, uint8_t pinN)
Same as above but with differential measurements.

int ADC::readSingle() 
Reads the analog value of a single conversion. Set the conversion with with startSingleRead(pin) or startSingleDifferential(pinP, pinN).


Teensy Forum: User Pedvide 
Github: Pedvide/ADC 
Freescale: K20 Sub-Family Reference Manual 
Freescale: App Note - ADC measurements done properly
Freescale: Using DMA to Emulate ADC Flexible Scan Mode on Kinetis K Series 
Freescale: App Note - AN2438/D 2/2003 ADC Definitions and Specifications 

Wednesday, 1 April 2015

Repetier successfully connected and functional with Marlin Firmware on Teensy 3.1

 I've had a few informative back and forth emails with Nikki V from Freescale regarding my failure to get connected to Repetier Host from the Marlin Firmware on my Teensy 3.1.  

(Here's a link to Nikki's 3D printer blog:

As mentioned in my previous article, I was finally able to compile and install the Marlin Firmware when I used the fork that Paul Stoffregen started, along with Nikki's Configuration.h and pins.h files. However, I could not connect to the firmware with Repetier.   

Marlin was sending the appropriate communications out through the USB serial port, as evidenced by this screenshot: 

But the Repetier connect request was not initializing Marlin, and returning the printer information.

Nikki pointed me back to the same thread on the Teensy Forum that I've already read 100 times... 

Yeah... but I'm apparently blind or ignorant... or both...

She brought my attention to the fact that this issue has already been identified, and could be remediated  by clicking a "fake OK" button from within the Manual control page.
I couldn't find the "Fake OK" button, so I read a little deeper.

And then Paul chimed in with a comment about compiling on Linux, and it all came together... Thank you Nikki, Thank you Paul.

Here's what Paul had to say that made all the difference: 

I tried the Linux version. It also has only "OK", not "Fake OK", but it seems to work fine.
I had to edit the baud rate to 57600 in Configuration.h. The Linux driver doesn't seem to like 250000 (even though Teensy 3.1 complete ignores the baud rate).

Repetier-Host does seem to be getting hung up on something and requires the "OK" button clicked. I believe it's due to the missing temperature feature. The blue bar will stay stuck as "1 Command Waiting". Clicking "OK" gets it unstuck.

I set the baudrate in configuration.h to 57600, and recompiled and uploaded to the Teensy 3.1.  I then launched Repetier, and went into the printer configuration, and selected 57600.

I applied, saved, and hit "Connect" .....

And Voila!


 Marlin Firmware now connects, and provides printer information. 

As of today, I have hard wired in 100k thermistors for Extruder and Bed heater temperature sensing, and set the pullup resistors for the endstops...

The Quadrature encoders are functioning on X and Y axis via the Flextimer module QuadDecode library, and *MY* PID routines (using the Arduino PID library)  are successfully driving both X and Y axis DC motors from the manual controls in Repetier.

The Quadrature encoders are functioning on Z axis with Phase A/B hardware pin interrupts , and *MY* PID routines  are successfully driving one Z axis DC motors from the manual controls in Repetier.

I have a functional I2C 20x4 LCD display, as well as SDcard reader.

As far as capacity on the Teensy, here is the size of code  - all in - so far:
From the Arduino IDE:
Binary sketch size: 108,816 bytes (of a 262,144 byte maximum)
Estimated memory use: 14,080 bytes (of a 65,536 byte maximum)

Is it running... sure... is it printing... no... my budget hasn't allowed me the pleasure of a real extruder. I'm simply stepping a NEMA17 I had kicking around.    I keep saying "next paycheck!"


  1. Acquire a real extruder/hotend  (today I'm simply driving a NEMA17 that I had kicking around.)   (anyone want to help??  LOL)
  2. Wire up FET transistors to drive extruder and bed heater elements
  3. Wire up endstops 
  4. Lots and lots and lots of PID tuning.  Things have changed since porting/merging my DC motor code into the Marlin Firmware.
  5. Take video this weekend and upload to Youtube!  LOL 
  6. Remove MY PID routines, and create macro/wrapper to use existing Marlin PID routines meant for temperature management.
  7. Put "conditional" code back in so I can merge this stuff back to github
  8. Figure out how to merge stuff back to github 
  9. figure out whether 7. or 8. should come first...