Photos

Four years ago Teensy 3.0 was launched, with your help backing the first production run. Since then, minor hardware updates and a tremendous amount of software development has occurred.

Now we're at it again, with two dramatically more powerful Teensy models that offer a big step up in performance and peripherals. I'm really excited about the amazing possibilities this powerful hardware will open up. Much more detail is available here. I hope you'll take a look and consider backing this project if you're interested.

As I search for a workaround, I'll be posting info and test code to this thread. I mostly use Linux and have only a couple Windows machines for testing. If you have Windows 7 or 8 and you're willing to help test experimental code, I could really use your help!

Kickstarter Status

This Kickstarter is effectively completed. We have fewer than 10 rewards unshipped, and all of those are due to no survey response and no reply to several emails. We're still trying everything we can to contact these last few people....

We've been shipping Teensy 3.0 boards via normal website orders, using the remainder of the second batch made for this Kickstarter. Nearly all orders are shipping the same or next business day. These are the Teensy 3.0 order pages.

Today the third batch of Teensy 3.0 boards is going into manufacturing. These new boards are the first with the improved USB pad design. See Update #17 for details. They are scheduled to be completed before the current batch runs out, so we should have ready-to-ship stock for all orders.

I intend to keep posting updates here, but at a slower pace of only 1 or 2 per month. Robin created an announcements forum where you can follow individual developments as they happen.

Support Forum

For project guidance and tech questions, please use the forum. You post code, screenshots and other info, edit your posts, and have a dedicated topic. Kickstarter's comments don't have those features, so please use the forum for any serious questions. Of course, comments here are perfectly fine for casual conversation.

Software Update #7

Here is another software update. This versions fixes several minor bugs and adds support for Arduino 1.0.2 (released yesterday).

I've also released Teensyduino 1.10, which includes all the Teensy 3.0 stuff except the ARM compiler. This release represents a bunch of work to bring Teensy 3.0's development back to the Teensyduino installer.

Rewards Shipping Status

All but 10 of the rewards have shipped. Today received the shipping address and other info for one. Robin says it will ship tomorrow, leaving only 9 rewards left. All 9 of those have no response to the survey and no response to multiple messages sent using kickstarter and direct email. Kickstarter only gives us email addresses, so we can't ship those last 9 until we get responses. If you're one of those final 9, please email Robin directly, robin at pjrc dot com.

Teensy 3.0 is selling normally now from stock with nearly all orders shipped same-day. Both with and without pins have plenty available. Here's the pages.

Future Updates

With this Kickstarter effectively completed, I'll probably post projects updates only when new software releases add major features.... and I am indeed working on them: missing USB types, various Arduino libraries, etc.

To follow Teensy 3.0 more closely, especially regarding specific library compatibility or minor features, please use the forum. That's where most of the conversation will be.

Thanks for backing the Teensy 3.0 launch here on Kickstarter. Your support helped us get Teensy 3.0 out to the world much more quickly. I really appreciate it. Thanks again! :-)

Rewards Shipped

As of today, nearly all the Teensy 3.0 rewards have shipped. Hand soldering the pins took time. Thank you for your patience.

Special Thanks to Robin & Erin

I'd like to give special thanks to Robin and Erin - the other 2 people behind PJRC. They've done an amazing job, putting in lots of long hours over the last month, to get all these rewards shipped.

Robin processes all the orders, prints invoices, and handles all sorts of business and logistical issues.

Erin does the testing (with the bed-of-nail tests, see Update #2), packages the products and does the mailing. She also solders the pins.

Well, Almost All Rewards Shipped, Except....

Only 35 rewards have not shipped. 9 are missing payment for an extra item (we're waiting until Thursday before just shipping without the extra stuff), 11 have unresolved problems with the survey, and 15 have absolutely no response. Kickstarter and Amazon do not automatically give us shipping addresses, so without a response with the shipping address, we simply can't send those rewards. If you're one of those 26, please contact us!

Many names on Kickstarter are aliases or nicknames, and disposable email addresses are used. This makes matching up a challenge. We need to hear from you in a messages sent through kickstarter, so we can be certain we're using your payment to send for your shipping!

Fast I/O: digitalWriteFast

Sometimes you need the fastest possible speed when manipulating the I/O pins. Teensy 3.0 has a digitalWriteFast(pin, state) function for this purpose. When you use digitalWriteFast with a constant for the pin number, and either HIGH or LOW for the state, it compiles to a single bus cycle. Likewise, digitReadFast() gives you optimized pin reading.

On AVR, it's been common practice to directly access the hardware registers. A few people have asked about doing the same on Teensy 3.0. You certainly can, but I would highly recommend using digitalWriteFast() and digitalReadFast(). As long as the inputs are constants, these optimize to direct register access, but you can keep nice easy-to-read code in your project.

Teensy 3.0 Forum, Coming Soon....

I'm planning to set up a web forum on PJRC, dedicated to Teensy products. Actually, I purchased vBulletin months ago, but I've been crazy busy developing Teensy 3.0 all this time. Many of you have asked for this. It's coming soon.

Software Schedule

Crazy as it sounds, I'm taking a break for a few days on the software. This week I'm focusing on documentation and answering the giant backlog of questions.

Real-Time Clock Support

This software release provides support for Teensy 3.0's on-chip RTC. To use it, you'll need to solder a 32.768 crystal to the board. A 3 volt coin cell is optional, but without the battery the RTC will lose track of the date and time when power is turned off.

The recommended crystal is Digikey 300-8303-ND. Any similar 32.768 kHz, 12.5 pF crystal should work. The crystal can be placed on either side of the board, but I highly recommend soldering from the bottom side, to avoid accidentally touching or solder bridging to any of the tiny top-side parts.

The set() function sets the time, using a 32 bit unsigned integer. The common convention is the number of seconds elapsed since 1970. The RTC simply increments the number every second. The get() function gives you the current time.

Once the RTC is running, uploading new code does not reset it. You can click Upload in Arduino over and over, without losing the current time. If a battery is connected, the time will be maintained while power is off.

The compensate() function lets to adjust the speed of the clock slightly. If it's running too fast, call compensate() with a negative number to slow it down a bit. The adjustment is approximately the ppm/8. If you use compensate(-40), the clock is slowed by 5 ppm (parts per million).

If you know how your crystal response to temperature, you could measure the temperature with analogRead(38) and use the results to change the crystal compensation as the temperature changes!

These 3 functions alone aren't very usually very interesting. To handle time and date in hours, minutes, seconds, days, months and years, Michael's Margolis's Arduino Time library is very helpful. The get() function is intended to be used with Time's setSyncProvider(). In File > Examples > Time > TimeTeensyRTC is a simple example.

Over the last few days, Michael and I have talked about how to port his Time to ARM. The Time library included in this software release is a preliminary port. It should work well, but please be aware future versions may change slightly.

Touch Sensing

The touchRead(pin) function is finally implemented. It works similarly to analogRead(pin). Just call the function with one of the pins that has touch sensing, and it will return a 16 bit number representing the capacitance on that pin, in 1/50th pico-Farad units. If the pin has 40 pF, you'll get 2000.

The measurement is the capacitive coupling to ground. For human touch interfaces, the best results are when the person's body is physically connected to ground. With hand-held devices, usually the enclosure has exposed metal for this purpose. It still works reasonably if Teensy's ground is connected to earth ground, usually through the USB cable. But running from a battery (called "floating") or connected to a laptop computer running from its battery doesn't work well.

Of course, it's possible to implement capacitive sensing using ordinary pins. The CapSense library does it quite well. But Teensy 3.0's built-in hardware gives you 3 things you can't get from software-based capacitive sensing.

1: Sensitivity: By default, touchRead() gives 0.02 pF sensitivity.2: Speed: The measurement time depends on the capacitance. A worst-case measurement takes about 5 ms. Typical capacitances used for human touch typically read much faster. Even when cycling through all the touch sensitive pins, you get excellent sensitivity at very responsive speeds.

3: Stability: The measurement works by comparing the pin's capacitance to an on-chip reference capacitor. If the power supply voltage, charging and discharging currents or other electrical factors change, their effect on the measurement are largely canceled out by using the same on-chip hardware to measure both the pin and the reference capacitor.

The common use is to replace buttons and sliders with touch-sensitive controls. But with 0.02 pF sensitivity, perhaps touchRead() can be used for other very interesting projects?

Bugs Fixed

Reproducible bugs reports really, really help. Most of the bugs fixed in this release are due to bug reports I received.

The SPI.setClockDivider() but reported by John and Thomas is fixed.

Many missing files were added, and minor edits made, so Ethernet now compiles. So far, Ethernet is untested on Teensy 3.0. If you do try Ethernet, please keep in mind the Wiznet W5100 chip draws more than the 100 mA current Teensy 3.0 can provide on the 3.3 volt pin. An external regulator or source of power for the W5100 is needed.

I added wiring_private.h, prog_uchar() and other things needed for Adafruit's ST7735 and Adafruit_GFX libraries, as reported by Joh Lummel. Sadly, there is still a remaining linker error. If anyone has insight into this problem, please contact me.

I added the missing digitalPinToTimer() function needed by the alternate LiquidCrystal library, as reported by Kgrider. This library is still untested, but it now compiles and looks like it should work.

A file naming bug preventing the EEPROM library from working on non-Linux systems was fixed. Thanks to Alex Ferro for reporting this.

XBee Library

I sent a small XBee library patch to Andrew Rapp. It was failing to compile because it assumed "Serial" is of type "HardwareSerial". On Teensy, Serial is a USB virtual serial. The same is true on Arduino Leonardo. The patch allows XBee to work on both boards.

Andrew and I exchanged a few messages. Many people have wanted to use the XBee library with the software serial library. Even though it's not very useful for Teensy 3.0 (which has 3 real hardware serial ports), I created a patch for XBee to allow use of software serial, or any Arduino Stream compatible library.

Andrew published the code as a 0.4 beta test. If you're using an XBee on a regular Arduino board, please give a try and send Andrew some feedback.

SdFat Library

Beta 4 was the first version to support the SD library (not impacted by the SPI.setClockDivider bug).

Since beta 4, I've exchanged several messages with Bill Greiman, author of the SdFat library. Bill has been working on a newer, faster versions. The one that comes with Arduino is fairly old. He sent me a beta test version, and a patch to make it compile in the 32 bit environment.

Teensy 3.0's SPI port is capable of 24 Mbit/sec speed. That's 3 times faster than the AVR-based Arduino. It also has a small FIFO and DMA transfer capability. My initial support for the SD library involved emulating the AVR SPI port. I spent a couple days fiddling with native routines, which admittedly were probably only a start at a truly native solution.

Bill optimized the native code and put it in his faster library. Here is a benchmark result he posted.

I should mention this is probably not even "beta" code at this point. It's also worth keeping in mind the speeds vary quite a bit from one SD card to another.

Still, it's pretty exciting seeing such impressive read and write speeds. This could really open up a lot of amazing project possibilities.

FastSPI Library

I also spent some time talking with Daniel Garcia (author of the FastSPI library) and Mark Kriegsman, about driving huge numbers of RGB LEDs. Last weekend they worked with a couple Teensy 3.0 boards, and got them driving LEDs. Here's a photo Mark sent of the first light, on October 14, 2012:

Later that day, Dan had a strip of 160 LDP8806 LEDs refreshing at 1300 frames/sec. Since then, I've heard he has some preliminary support for Teensy 3.0 in the library. I believe some pretty exciting LED driving projects are likely to happen!

I'm personally very interested to try using combinations of DMA channels to synthesize the special waveforms needed by some of 1-wire the addressable RGB LED driver chips. That's a complex topic that could fill a huge posting all by itself. For now, it's taking every ounce of self-restraint I have to resist the RGB LED urge....

Issues Running 8 Bit AVR Code on 32 Bit ARM

Since I started working on Teensy 3.0 over a year ago, and especially in the recent months as more people have heard about the project, I've regularly been asked what types of problems arise when adapting 8 bit Arduino code to a 32 bit platform.

So far, there are been remarkably few issues involving the different size of int, pointers and other basic data types. Most code is really quite well written. The relatively small number of issues are usually caught by the compiler. But one turned up today....

Jonathan Sorensen reported a problem that turned out to be code that compiles without error, works on 8 bit AVR, but fails when run on 32 bit ARM. It's a library from Pololu for their LSM303-based Inertial Measurement Unit.

Here is the code. a.x is a float, and xha and xla are bytes from an accelometer. Can you spot the bug, without peeking at the explanation below?

a.x = (xha << 8 | xla) >> 4;

The 2 bytes, xha and xla, were read using the Wire library. Together they form a 2's complement number. This code reassembles the 2 bytes, divides by 16, and then assigns the result to the float.

Both AVR and ARM combine the two halves to the correct 16 bit result. The hidden gotcha is the right shift operation. You might expect this to simply shift the bits to the right, but what goes into those "empty" most significant bits? It's not necessarily zeros. On AVR, it's handled as a signed integer, so if the number is negative, the left-most 1 bit is replicated to the 4 empty bits.

On ARM, it's also handled as a signed integer. But instead of an integer with a range of -32786 to +32767, it's an integer with range -2147483648 to +2147483647, which happens to be using a small 0 to 65535 portion of that huge 32 bit range. When the sensor reads positive, the result is correct. But when negative, the result is a wrong positive number.

Even without the right shift, the same problem would occur while converting the integer to a float (and does indeed happen elsewhere in this library). To the compiler, the unsigned logical or only becomes a signed integer if the result exactly matches the size of the result. A type cast is needed, so the desired 16 bit signed integer is always used.

a.x = (int16_t)(xha << 8 | xla) >> 4;

Normally, even code that packs bytes into large variables works fine. But depending on sign extension from an intermediate result with implicit type is a hidden gotcha, which probably isn't obvious to many programmers.

Missing Features, Coming Soon....

At the top of my to-do list are 2 of the missing USB Types: Keyboard/Mouse/Joystick and MIDI. Teensy 2.0 supports these, and several others. In time, I'll do them all on Teensy 3.0, plus a few more I have planned.

Also extremely urgent is an AVR-like ISR() macro and interrupt vector table scheme. Since beta 2, attachInterrupt() has worked. But if you want to use any of the interrupts directly, the only way to do so is editing the table in mk20dx128.c. Soon I'm going to rework that file and the linker script, to support a system that look and works very much like what everyone is used to on AVR.

While testing SdFat, Bill Greiman discovered problems with malloc/free. He sent me a very detailed, very helpful description. It turns out the newlib library malloc was designed for and defaults to settings that make sense for a large memory system. It requests memory in 4K blocks, which is very large for such a small microcontroller. I'm going to try porting or reimplementing the avr-libc malloc/realloc/free system, with minor modification for 32 bit word alignment.

The other item on my urgent to-do list, which probably needs some explanation, is Arduino reset emulation. Traditionally, Arduino has used a 2 chip design, where the USB to serial converter is a dedicated chip. When you open the Arduino Serial Monitor, the change on the DTR signal resets the AVR chip, causing your program to restart a fraction of a second after the serial monitor window appears. It's a very convenient feature (though some people might prefer their board never automatically reset). Lots of Arduino sketches and library example depend upon this automatic reset behavior.

For years, Teensy 2.0 has emulated this 2-chip reset behavior, using only a single chip. It's tricky. Interrupt-based code parses a restart request, which is sent as the serial monitor window is opening (Teensy doesn't use DTR, so it the auto-reset isn't easily happen by accident while using non-Arduino software).

Microsoft's driver has terrible bugs which are triggered if the device instantly resets before the request is acknowledged, or before a couple more followup requests also complete successfully, so a software-based timer is started. When the timer elapses, a reset is simulated by shutting down all the on-chip peripherals and jumping back to location 0. But the USB port is left operating, as if nothing happened. Then the USB initialization code checks to see if the USB is already running. If it is, an alternate initialization is done. If not, the USB is initialized. All the critical USB state variables are located in a special "noinit" memory section, so the C runtime startup code doesn't overwrite them. When actual cold USB startup is done, they all have to be written, even if they're zeros.

If that sounds like an overly complex implementation for a minor feature, perhaps it is? But years of experience with Teensy 2.0 shown it really makes a big difference in usability. It's also really convenient. I'm going to implement it in Teensy 3.0 soon.

Wanted: Reproducible Bug Reports

Bug reports with the complete code and steps needed to reproduce the problem are incredibly helpful. Please, if you find a bug, or any library or sketch that isn't compatible, I want to know about it!