New Teensy user

Status
Not open for further replies.

ralphhipps

Active member
howdy all!

I'm new to the Teensy, but I've used a few flavors of Arduino for about 3.5 years now.

I've noticed there are some differences. =)

what would be really helpful (and I haven't found yet) is a web page or something that has code examples for how to do stuff on Teensy, esp things that are different from the Arduino.

I'm using Teensyduino on the Arduino IDE. I have found the examples there, which are great, just looking for something to cover the basics, perhaps a comparison where there are differences, like Interrupts.

Any suggestions? Anything I'm missing?
 
https://www.pjrc.com/teensy/teensyduino.html and then all the items in the Teensyduino submenu in the left sidebar...

But most things are made to preserve a maximum of compatibility with Arduino out of the box. So, attachInterrupt(pin,MODE) will work on Teensy without problems, although the source code behind that function will be very different from the Arduino version, but the users don't have to care.

Only a few Arduino things like addressing the AVR hardware (timer, gpio and interrupt) registers directly will naturally fail on the ARM processors which are completely different inside. For these, PJRC has published the reference manuals of the different Teensy CPUs on their website.
 
Welcome to the club. I too switched from Arduino to Teensy and have been wildly happy with that move
1. better product
2. better help from the Forum (and friendlier)

I have found nearly 100% compatibility between Arduino and Teensy. Stuff like serial definition, PWM assignment and a few other code differences exist, but really not that hard to change. Even if your program had to be a total rewrite--which can't happen, it's well worth the change.

There are some very helpful and talented people on this forum, so feel free to ask for help.
 
I've had generally good luck, but a couple libs here and there won't compile, like Pixy2 (pixy is ok), or PFC8574T I2C LCD interface.

Qs:

1. for INT, do I need to do this? seems to be working, but not needed for Arduino:

//To use interrupts, you must include the AVR interrupt header
#include <avr/io.h>
#include <avr/interrupt.h>

2. I2C, wd like to access the extra ports.

it would appear I need to use this below, any other ways to do it?

https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3
 
Q: this ain't workin:

#define shutDownPinRC 33 // for RC switch

this always returns zero:

digitalRead(shutDownPinRC);

I can measure the pin voltage with a DMM, I can see it go high (3.3 V) or low (0 V).

is there something special about pin 33?

I'll triple check my code.
 
code below:


// OpenLCD is an LCD with Serial/I2C/SPI interfaces fr SparkFun Electronics
int lineNum, charNum;
int lineNumMap[4] = {0,64,20,84}; // to map line numbers

#define shutDownPinRC 33 // for RC switch

// LED pins
#define LED_RED 24 // turn on if obstacle detected (OBS)
#define LED_YEL 25 // turn on if at wp, turning to new course
#define LED_GRN 26 // turn on if cone detected (cone)
#define LED_BLU 27 // turn on if.... ?
#define PN2222_PIN 28 // controlled by deadman, drive high to turn on PN2222, enable 555, siren

int success = 0; // 1 = success/done

// debug
byte debug = 1; // 1 = turn on debug code. 2 = turn on timing code


////////////////////////////////////////////////////////////////////////////////
void setup() {
////////////////////////////////////////////////////////////////////////////////

if (debug >= 1) {
Serial.begin(115200); // no line ending in terminal
delay(1000); // teensy needs time to get ready
}

Serial1.begin(9600); // Begin communication with Serial1 for OpenLCD
LCD_clear(); // forces the cursor to the beginning of the display

// setup pins for various IO functions
pinMode(LED_RED, OUTPUT); // pin 38
pinMode(LED_YEL, OUTPUT); // pin 40
pinMode(LED_GRN, OUTPUT); // pin 42
pinMode(LED_BLU, OUTPUT); // pin 42
// LED test
digitalWrite(LED_RED, HIGH); // OBS det
digitalWrite(LED_YEL, HIGH); // wp arrival, turning to new course
digitalWrite(LED_GRN, HIGH); // Cone det
digitalWrite(LED_BLU, HIGH); // Cone det
delay(2000);
digitalWrite(LED_RED, LOW); // OBS det
digitalWrite(LED_YEL, LOW); // wp arrival, turning to new course
digitalWrite(LED_GRN, LOW); // Cone det
digitalWrite(LED_BLU, LOW); // Cone det
// end LED test


} // end setup




////////////////////////////////////////////////////////////////////////////////
void loop() {
////////////////////////////////////////////////////////////////////////////////

LCD_setCursor(0,0);
Serial1.print("shutDownPinRC: ");
LCD_setCursor(1,0);
Serial1.print(digitalRead(shutDownPinRC));
LCD_setCursor(2,0);
Serial1.print(shutDownPinRC);
if (debug == 1) {
Serial.print("shutDownPinRC: ");
Serial.println(digitalRead(shutDownPinRC));
}
delay(100); // debug only

}

// -------------------------------------
void LCD_clear() {
// Send reset command - this forces the cursor to the beginning of the display
// LCD_clear();
Serial1.write('|'); // Send setting character
Serial1.write('-'); // Send clear display character
}

void LCD_setCursor(int lineNum, int charNum) {
// Jump cursor to line, position
// LCD_setCursor(3,19);
Serial1.write(254); // Send command character
Serial1.write(128 + lineNumMap[lineNum] + charNum); // 0, 64, 20, 84, 0-19
}

/*
LCD_clear();
LCD_setCursor(3,19);
*/
 
Until a Teensy digital pinMode() is set - it is not ready for use:
This is needed in:
Code:
setup() {
   // ...
   pinMode ( shutDownPinRC, INPUT );
   // ...
}
Maybe not made clear enough on that linked page - but it is shown here:
Code:
[B]A Complete Example[/B]
This simple example blinks the LED slowly when the pushbutton is not pressed, and blinks rapidly when it is pressed. The pushbutton is connected to the D7 pin and ground, and the pullup resistor is used to make the pin high when the button is not connecting it to ground. 
void setup()
{
  pinMode(PIN_D6, OUTPUT);       // LED
[COLOR="#FF0000"]  pinMode(PIN_D7, INPUT_PULLUP); // Pushbutton[/COLOR]
}
 
Until a Teensy digital pinMode() is set - it is not ready for use:
This is needed in:
Code:
setup() {
   // ...
   pinMode ( shutDownPinRC, INPUT );
   // ...
}
Maybe not made clear enough on that linked page - but it is shown here:
Code:
[B]A Complete Example[/B]
This simple example blinks the LED slowly when the pushbutton is not pressed, and blinks rapidly when it is pressed. The pushbutton is connected to the D7 pin and ground, and the pullup resistor is used to make the pin high when the button is not connecting it to ground. 
void setup()
{
  pinMode(PIN_D6, OUTPUT);       // LED
[COLOR="#FF0000"]  pinMode(PIN_D7, INPUT_PULLUP); // Pushbutton[/COLOR]
}


ok, I found what works is a slight variation of that:

pinmode(shutDownPinRC, INPUT);

the PIN_D7, etc., syntax errors out during compilation. I'm using tduino 1.46 and arduino 1.89, targeting T3.6.

interestingly, if I attached shutDownPinRC to an INT it reads the pin fine without the pinmode declaration. I found I didn't want an INT on that, hence all the problems. =)

Also I found that INPUT_PULLUP doesn't work, tried it on a couple of other pins reading switches that ground on closure. I hear the pullup is 25 ohms, but those pins always read zero even when switches were open. External 2.2 k pullups worked on those.

so I've learned a couple of key diffs between Teensy and Arduino for GPIO. You MUST declare input mode (unless it's used as INT), and pullups don't work.
 
trying to use the updated i2c_t3 library instead of Arduino wire.h, so far not much luck:

Arduino: 1.8.9 (Linux), TD: 1.46, Board: "Teensy 3.6, Serial, 180 MHz, Faster, US English"

/tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o: In function `i2c0_isr':
/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire/WireKinetis.cpp:895: multiple definition of `i2c0_isr'
/tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o:/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/i2c_t3/i2c_t3.cpp:1134: first defined here
/home/ralph/arduino-1.8.9/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Disabling relaxation: it will not work with multiple definitions

/tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o: In function `Print::availableForWrite()':
/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire/WireKinetis.h:132: multiple definition of `i2c1_isr'
/tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o:/home/ralph/arduino-1.8.9/hardware/teensy/avr/cores/teensy3/Print.h:61: first defined here

/tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o: In function `Print::availableForWrite()':
/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire/WireKinetis.h:132: multiple definition of `i2c2_isr'
/tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o:/home/ralph/arduino-1.8.9/hardware/teensy/avr/cores/teensy3/Print.h:61: first defined here

/tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o: In function `Print::availableForWrite()':
/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire2'
/tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o:/home/ralph/arduino-1.8.9/hardware/teensy/avr/cores/teensy3/Print.h:61: first defined here
/home/ralph/arduino-1.8.9/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire2' changed from 20 in /tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o

/tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o: In function `Print::availableForWrite()':
/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire1'
/tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o:/home/ralph/arduino-1.8.9/hardware/teensy/avr/cores/teensy3/Print.h:61: first defined here
/home/ralph/arduino-1.8.9/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire1' changed from 20 in /tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o

/tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o: In function `Print::availableForWrite()':
/home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire'
/tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o:/home/ralph/arduino-1.8.9/hardware/teensy/avr/cores/teensy3/Print.h:61: first defined here
/home/ralph/arduino-1.8.9/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire' changed from 20 in /tmp/arduino_build_957573/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_957573/libraries/Wire/WireKinetis.cpp.o

collect2: error: ld returned 1 exit status
Error compiling for board Teensy 3.6.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

verbose option showed:

Using library i2c_t3 in folder: /home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/i2c_t3 (legacy)
Using library VL53L1X at version 1.0.1 in folder: /home/ralph/code/libraries/VL53L1X
Using library Wire at version 1.0 in folder: /home/ralph/arduino-1.8.9/hardware/teensy/avr/libraries/Wire

not sure why Wire is being used, not in the code as far as I can tell:

/*
for Teensy 3.6

This example takes range measurements with the VL53L1X and displays additional
details (status and signal/ambient rates) for each measurement, which can help
you determine whether the sensor is operating normally and the reported range is
valid. The range is in units of mm, and the rates are in units of MCPS (mega
counts per second).
*/

//#include <Wire.h> // Arduino Wire Library

#include <i2c_t3.h> // Teensy I2C lib at https://github.com/nox771/i2c_t3
//default pin setting SCL/SDA:
//- Wire: 19/18
//- Wire1: 37/38 (3.5/3.6)
//- Wire2: 3/4 (3.5/3.6)
//- Wire3: 57/56 (3.6)



#include <VL53L1X.h>

VL53L1X sensor;

void setup()
{
Serial.begin(115200);
delay(250);

Wire2.begin();
Wire2.setClock(400000); // use 400 kHz I2C

sensor.setTimeout(500);
if (!sensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1);
}

// Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
// You can change these settings to adjust the performance of the sensor, but
// the minimum timing budget is 20 ms for short distance mode and 33 ms for
// medium and long distance modes. See the VL53L1X datasheet for more
// information on range and timing limits.
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(50000);

// Start continuous readings at a rate of one measurement every 50 ms (the
// inter-measurement period). This period should be at least as long as the
// timing budget.
sensor.startContinuous(50);
}

void loop()
{
sensor.read();

Serial.print("range: ");
Serial.print(sensor.ranging_data.range_mm);
Serial.print("\tstatus: ");
Serial.print(VL53L1X::rangeStatusToString(sensor.ranging_data.range_status));
Serial.print("\tpeak signal: ");
Serial.print(sensor.ranging_data.peak_signal_count_rate_MCPS);
Serial.print("\tambient: ");
Serial.print(sensor.ranging_data.ambient_count_rate_MCPS);

Serial.println();
}
 
the Basic Master example compiles fine, even when I change the port:

Wire2.begin(I2C_MASTER, 0x00, I2C_PINS_3_4, I2C_PULLUP_EXT, 400000);

must be something to do with the VL53L1X library, I guess, that causing the conflict.
 
Both the Wire library as well as i2c_t3 library define and use a bunch of the same resources. As such any one sketch can use one or the other but not both. This includes any libraries that is included in your sketch (or libraries that other libraries include).

So if you are going to use i2c_t3, you need to go through all of the libraries you are using and change them to use i2c_t3 instead. You may want to then rename that library as to not conflict with use wire instead for other projects, that use that library.

Also note, that i2c_t3 is not a direct replacement for Wire library. They are mostly compatible, but they both handle the ability to use alternate pins for SCL and SDA. And likewise probably some other differences as well.

Kurt
 
Interrupts: near as I can tell this doesn't work, actually hangs the T3.6 when I call cli();

"The simplest and most common approach is to simply disable the global interrupt setting with cli() and reenable with with sei()."

cli();
// setup pin for RC controller deadman switch
pinMode(shutDownPinRC, INPUT);
attachInterrupt(digitalPinToInterrupt(shutDownPinRC), readDeadman, FALLING);
 
Also anyone have any experience with the Teensy and the Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout?

they don't seem to be compatible at all, but it works fine with Arduino.
 
Each I2C bus can communicate with more than 100 devices as per specifications. All Teensy 3.x have at least 2 I2C busses, so, one might connect up to 200+ devices. Where is the need for a multiplexer?
 
well, I have some VL53L1X Lidar rangefinders that all have the same I2C address. =)

also the Teensy I2C library has been a bit problematic so far, but I haven't spent much time on it trying to work around the library issues with sensors, etc., so I only can get one I2C port up and running.

I'll have more time to debug this maybe in a week or two, that should help.
 
Interrupts: near as I can tell this doesn't work, actually hangs the T3.6 when I call cli();

On this forum, we ask that you show a complete program. Complete means anyone can copy it into Arduino and upload it to the same board you're using, to recreate the problem.

I know this is extra work for you. But it is worth your time to do this. We are very good at helping here when you show a complete program. Sometimes we figure out what's wrong without complete info, but even when we do, it takes a lot more time for everyone to guess the missing details.

I can tell you, cli() and sei() do work on Teensy 3.6. However, using these in the wrong way can cause your program to stall. Teensy 3.6 is different hardware than Arduino Uno, so techniques that are correct for one aren't necessarily proper for the other. Details matter. That's why we have the "forum rule" at the top of every page. Please, do yourself a favor and save everyone's valuable time by showing a complete program. We can help you much better that way.
 
Understood, and I can see how it would be tough to debug without context. It's good to know they do work.

I have removed the code for cli & sei from my project, but the above was basically the meat of it.

to get things working again I just removed the cli & sei lines.

based on debug serial statements the execution stopped at cli();

I'll dig around further on the forum and see if I can figure out what I'm doing wrong.
 
Status
Not open for further replies.
Back
Top