Teensyduino 1.14 Release Candidate #1 Available

Status
Not open for further replies.
Here's a list of the changes since Teensyduino 1.13:


Fixed Ethernet DNS client bug on Teensy 3.0.

Added partial SoftwareSerial for Teensy 3.0. If the pins match one of the real serial ports, hardware serial is used. This allows use of libraries that are hard-coded for SoftwareSerial. If non-serial pins are specified, only transmit works. Software-based receive is not yet supported (but planned for a future release)

Updated Time library. "atime_t" on Teensy 3.0 changed back to "time_t". Date strings fixed on Teensy 3.0. NTP and GPS sync examples updated for Arduino 1.0.4. Many other fixes and improvements to the Time library examples.

Added DS1307RTC and TimeAlarms libraries (companions to Time library).

Linux select-paste supported (Arduino 1.0.4 only, Linux only)

Added "Copy To Clipboard" button for compile errors (Arduino 1.0.4 only)

Turkish keyboard layout special keys supported for USB keyboard.

KEY_MENU name added for the menu key.

Memory tuning parameters (heap_start, heap_end, malloc_margin) supported on Teensy 2.0.

Fix compile error on Teensy 2.0 with ps2dev library.

Fix F() macro "const" when used with newer versions of avr-gcc.

Added DDR registers and pullup resistors to AVR port register emulation on Teensy 3.0.

Optimized Serial1.write(buffer, length)

Added IntervalTimer to Teensy 3.0 - Thanks to Daniel Gilbert

Added compiler defines to example makefile, for compatibility with Arduino libraries

Added cxa_guard_acquire / cxa_guard_release needed for some Ethernet library applications

Fixed brief glitch at the beginning of analogWrite()

Round analogWriteFrequency() to the nearest possible frequency

Fix micros() bug on Teensy 3.0 when read while interrupts disabled.

Fix IPaddress Printable usage on Teensy 3.0

Fix Serial1 when more than 8 bytes written with interrupts disabled.

Optimize Serial1 FIFO handling on Teensy 3.0, for dramatically less CPU time per byte.

Convert tone() on Teensy 3.0 to use IntervalTimer.

Use serial number for all USB types on Teensy 3.0.

Remove MIDI message names which conflict with MIDI 3.2 library.

Allow override of USB manufacturer, product and serial strings on Teensy 3.0. See usb_names.h.

Add makeWord() to Teensy 3.0.

Fix buffer overflow in String + long integer concatenation on Teensy 3.0.

Update AccelStepper library.

Update Encode library - now supports interrupts on all Teensy 3.0 pins.

Update PS2Keyboard library - French keymap, readUnicode() function, Teensy 3.0 interrupt support.

Update TinyGPS library
 
Turkish keyboard layout special keys supported for USB keyboard.

Good to see this. Looking at usb_keyboard.c, it seems that up to ten Unicode code points > 255 and > FFFF are supported per keyboard layout. This will work for Latin-oriented keyboards that have a small number of BMP characters. It won't be sufficient for keyboards with non-Latin scripts (Cyrillic, Arabic, Hebrew, Japanese, etc) although it could be extended to support them (probably 50 or so would be fine for most of them).

I notice that characters beyond FFFF are not supported in UTF-8 decoding.

Allow override of USB manufacturer, product and serial strings on Teensy 3.0. See usb_names.h.

My grasp of C/C++ is insufficient to understand what
Code:
__attribute__ ((weak, alias("usb_string_manufacturer_name_default")));
does. So you declare a variable of type
Code:
struct usb_string_descriptor_struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t wString[];
};
in your code and then fill in the values?
 
This will work for Latin-oriented keyboards that have a small number of BMP characters. It won't be sufficient for keyboards with non-Latin scripts (Cyrillic, Arabic, Hebrew, Japanese, etc) although it could be extended to support them (probably 50 or so would be fine for most of them).

When (or if) any of those keyboard layouts are created, the code can be extended. I had originally planned to use a pair of arrays. That may yet still happen. Or simply replicating the code might make sense?

My general design preference is to have a plan for supporting more features, but to actually build the code on an as-needed basis. Usually when I build lots of code far in advance, it all ends up being rewritten when the actual need arises.

I notice that characters beyond FFFF are not supported in UTF-8 decoding.

That's correct. Again, I prefer to build the code when it's actually needed, rather than designing a system than can support beyond u+FFFF before implementing any layout which needs it.

Do you know of any keyboards in widespread use where keystrokes map to unicode characters beyond u+FFFF?

Even this one could be supported within the u+FFFF limit...... ;)


So you declare a variable of type ... (struct usb_string_descriptor_struct) ... in your code and then fill in the values?

That's the idea. You must use the exact variable names (without the "_default" suffix) as defined in that header.

It's currently untested.
 
Last edited:
My general design preference is to have a plan for supporting more features, but to actually build the code on an as-needed basis. Usually when I build lots of code far in advance, it all ends up being rewritten when the actual need arises.
Yes, that is fair. "Can be extended in future" is fine; I was asking to distinguish from the "can't be extended, would need incompatible rewrite" case.

That's correct. Again, I prefer to build the code when it's actually needed, rather than designing a system than can support beyond u+FFFF before implementing any layout which needs it.

Do you know of any keyboards in widespread use where keystrokes map to unicode characters beyond u+FFFF?
Common use, no. By definition, the space beyond the basic multilingual plane is used for minority languages, historical languages, and lesser used characters in majority languages.

Which doesn't mean that they would be unused; someone working with such languages might well want to make an extra keypad to allow easy typing. As an example, classical scholars using the Unicode characters supported in the Alphabetum font.

But as you say, as long as extension is possible, that bridge can be crossed when someone posts about being unable to do it.

Even this one could be supported within the u+FFFF limit...... ;)
Yes, anything in the conlang registry is by definition not standardised by Unicode and thus can use the private use area of the BMP.

That's the idea. You must use the exact variable names (without the "_default" suffix) as defined in that header.

It's currently untested.
Thanks. I will see if I can test it out.
 
Just a note for any Arch users, or others who may have a minimal system:

It seems that the Teensy Loader requires libpng12 as an unlisted dependency. I only found out through turning on the verbose output after multiple compiles failed to open the Teensy Loader.
 
The USB serial seems to stop working after 8+ characters. To rule out any errors from previous versions, I've installed a fresh Arduino 1.0.4 (64 bit linux) from the arduino.cc website and ran the installer from the first post over this clean installation.

To test this I changed main.cpp in arduino-1.0.4/hardware/teensy/cores/teensy3/main.cpp to the following:

Code:
	// To use Teensy 3.0 without Arduino, simply put your code here.
	// For example:
    Serial.begin(9600);
    delay(1000);

	pinMode(13, OUTPUT);
	while (1) {
        Serial.println(Serial.available());
		digitalWriteFast(13, HIGH);
		delay(500);
		digitalWriteFast(13, LOW);
		delay(500);
	}
Which was uploaded with the standard Makefile and gnu make.

After connecting with 'screen /dev/ttyACM0 9600' to the serial port, everything seems fine until 8+ characters are typed into the serial port. Then the serial port becomes unresponsive, even though the led on the teensy keeps blinking.
 
After connecting with 'screen /dev/ttyACM0 9600' to the serial port, everything seems fine until 8+ characters are typed into the serial port. Then the serial port becomes unresponsive, even though the led on the teensy keeps blinking.

Yes, of course, this is exactly how it should work, because your program never receives the data. With the default settings, Teensy 3.0 is able to buffer up to 8 USB packets (you can change the number of buffers in usb_desc.h). In this case it's a single character placed into each packet.

You need to actually use Serial.read() to receive the data.

If you only ever call Serial.available(), the incoming data remains in the buffers, because you haven't read it. When all 8 buffers are full, Teensy 3.0 will no longer accept more incoming data. USB has very reliable flow control. It's supposed to work this way, so you can't lose data if the PC transmits faster than your program receives.
 
Last edited:
On a somewhat related note, I've been considering adding code on Teensy 3.0 to detect repetitive calls to Serial.available() and automatically merge the queued packets. Each package can hold up to 64 bytes, so this would theoretically expand the input buffer to 512 bytes for programs that send a single byte at a time.

It will only delay the inevitable if never call Serial.read(), but there are some programs out there which will call Serial.available() and wait for the return value to be larger than some expected message length before they use Serial.read(). If the PC side sends tiny USB packets, it's possible to use up all 8 buffers before enough data is queued.
 
Teensy 3.0 is able to buffer up to 8 USB packets (you can change the number of buffers in usb_desc.h). In this case it's a single character placed into each packet.
This explains it all. I expected a buffer which buffered the actual received serial bytes, instead of on the USB packets.

It will only delay the inevitable if never call Serial.read(), but there are some programs out there which will call Serial.available() and wait for the return value to be larger than some expected message length before they use Serial.read().
That's exactly what caused this 'problem' in my case. It's easy to fix of course, but perhaps the merge of several USB packets on the serial.available() would indeed be convenient.

Thanks for the thorough explanation.
 
Is there a reason that it's only delivered in an executable? I know this is common place in the Windows world, but it's really disturbing for some of us ingrained this way.
 
How would you suggest delivering something that makes patches to a third-party binary executable (the Arduino environment)?
 
I thought it was a simple overlay. However, I don't use the arduino executable either. It's klunky and frustrating for anyone used to a real editor. But Arduino source is downloadable too. The bigger point is that the exe is completely blind trust, there's not even a source tarball that you can see and believe you're getting the same thing if you chose to download an exectuable. There's no manifest saying what its doing.
 
I thought it was a simple overlay. However, I don't use the arduino executable either. It's klunky and frustrating for anyone used to a real editor.
Well, you can always use an external editor (File -> Preferences -> Use an external editor) within the Arduino IDE and just use the IDE as a simplified build and download tool.
 
How would you suggest delivering something that makes patches to a third-party binary executable (the Arduino environment)?
You can make such tools fairly easily. When I started work at Data General in 1979, we had a binary patching tool that DG would use to modify the operating system without having to send a whole binary release.
 
I really do want to provide an installation process that works well. Like most software projects, there are many conflicting goals and only finite hours available to try solving them all. Just to be realistic, in the near term many other software efforts like the readBytes() optimization are a much higher priority. Several other software and hardware developments, like audio and USB host, are also planned, as well as my ongoing efforts to test, port and document every widely used Arduino library. In fact, I have an overflowing box of hardware already purchased, just waiting for me to get around to testing a few dozen other libraries. When talking about software development, there's always much more to do than finite time allows, so I believe it's always good to keep priorities in mind.

The vast majority of people using Teensy do use Arduino, so my primary goal is to create a process that works best for the majority. The installer isn't perfect. In fact, I've often considered just providing a forked copy of Arduino. But I've always felt some reservation about forking Arduino. I really do prefer to work with them and contribute improvements back. Other boards like Maple and Chipkit that have forked the Arduino IDE have tended to drift farther from Arduino's ongoing development. I actually put a lot of work into the installer, only to avoid forking Arduino so we could work together better. In 2 weeks I'm planning to chat with Massimo at Maker Faire. We both want to talk about how PJRC and Arduino can better work together.

There are also a good number of more advanced users who don't like Arduino at all. I used to feel this way (and I do still edit mostly with vim). Early in Teensy's history, the development path involved WinAVR, or the Mac or Linux versions, and makefiles. That stuff is all still available for Teensy 2.0. I'm planning to overhaul the website soon. Those pages will not vanish and their URLs will not change, but the new structure will move them to a less prominent location in the hierarchy.

For Teensy 3.0, I recognized that keeping 2 separate code bases updated just isn't feasible. The less used one gets neglected and suffers bitrot. Rather than a C only and a mostly C++ code base, I tried to design Teensy 3.0's functionality mostly in pure C code using function names closely matching the older Teensy 2.0 C stuff. Then the Arduino C++ APIs like Serial, Serial1, Serail2, Serial3 are just a thin wrapper around the C code. If you look in hardware/teensy/cores/teensy3, you can see all this work. The idea has been to keep everything in a single code base which I can maintain, but can be used with Arduino and also without.

Long-term, I do intend to make a non-Arduino download. All that effort in Teensy 3.0's core library was done with this long-term goal in mind. At this point, I honestly don't know quite how that download will look. One thing is certain: I really need to build it from the same code base that goes into the installer, even if it's just a .zip or .tar.gz, so it's always up to date as new releases happen. With so many things in development, I don't see this happening until much later this year. But it is on my to-do list, and I'm certainly open to constructive feedback about how a non-Arduino download and install process could be work most effectively with the largest number of non-Arduino users.
 
I'm certainly open to constructive feedback about how a non-Arduino download and install process could be work most effectively with the largest number of non-Arduino users.
I think it would be a good option if a tar.gz/zip archive is offered on the website. This archive should contain just the necessities to use the Makefile which is currently present in the teensy3 core. This would be more convenient than the requirement to download a new archive from Arduino.cc and subsequently running the Teensyduino installer over it. Though it's not that big a deal, as it only needs to be done occasionally.

Somewhat related: I prefer to have my projects' code in a different directory than the Arduino folder. So I changed the original Makefile to prefix all the paths with the parameter 'ARDUINO_DIR'. I reckon most non-Arduino users do this, perhaps it would make sense to add this parameter to the default Makefile? Additionally; If I'm correct, the current Makefile does not handle libraries, my solution so far has been to copy the necessary library files to the project's working directory. I'm not sure how the Arduino environment includes the required libraries, but in case this can be done with the Makefile it would be nice if this could be included as well.
 
I have really limited cycles right now (with a baby in the house). But it frustrates me enough that I end up using my available cycles trying to get a makefile working to build it as static libs rather than actually working on my project. It's like an attractive nuisance I can't leave alone any time I start to work on it, and I get fixated on that instead. It's a lifelong curse of tool fixation. Sometimes I think my real hobby is tool making, and all these other hobbies are just a premise for it.

I have built static libs from core and the library components I need, in my project libs folder. I think that somehow I didn't get the initialization vector pulled in though, as even the simple stuff doesn't start. An infant in the house means that concentration is measured in tens of minutes rather than hours though.
 
swarfrat: You might want investigate if they use special linker scripts to get things like the initialization vector in a particular location.
 
Would be nice to have an apt-get repository, so you could just add pjrc as a source in linux. But certainly a low priority. Should make it easy for people to have a pristine arduino install, and a pristine teensyduino install.
 
swarfrat: you could have a look at the Teensy.mk Makefile I posted here:
http://forum.pjrc.com/threads/23605-Teensy-mk-port-of-Arduino-mk-Makefile

It builds static libraries, but I had to explicitly load the mk20dx128, usb_dev and usb_mem object files
(those files seem to be using a section() directive to locate code into memory).
I didn't have much luck with the -u linker option to force those symbols to load from the library
but I didn't try that hard...
 
IntervalTimer

IntervalTimer doesn't seem to work for me. If I try to flash a code using it, Windows tells me the board is not recognized any more and I cannot open Serial monitor for example.
Here is my test code :

#include "IntervalTimer.h"

const int ledPin = 13;

void timerCallback() {
Serial.println("ping");
}

void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);

IntervalTimer timer;
timer.begin(timerCallback, 1000000); // 1 second
}

void loop() {

//Blink (telltale)
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(1000);

}

Note that the led doesn't blink, actually it's like the board is crashed.
I also would like to know if this IntervalTimer is hardware or software based ? Is it accurate ?
 
Declaring "timer" inside setup is not a good idea. As soon as the code exits the setup function, the "timer" variable will not exist any more and will be overwritten by whatever else happens to be put on the stack when loop is called.
Declare "timer" as a global.
It's probably not a good idea to use Serial inside an interrupt routine either. I would change the code so that the interrupt routine toggles the ledPin (and loop will do nothing).

Pete
 
Declaring "timer" inside setup is not a good idea. As soon as the code exits the setup function, the "timer" variable will not exist any more and will be overwritten by whatever else happens to be put on the stack when loop is called.

That's an excellent point. I should really check to make sure IntervalTimer's destructor is properly releasing the hardware before the memory is reclaimed. Otherwise the next interrupt could cause a crash!
 
Status
Not open for further replies.
Back
Top