Teensyduino 1.20 Release Candidate #2 Available

Status
Not open for further replies.

Paul

Administrator
Staff member
Here is a second release candidate for Teensyduino 1.20:


Old beta download links removed. Please use the latest version:
https://www.pjrc.com/teensy/td_download.html



Please give this a try and report any bugs. Try to include a sample program that reproduces the problem!

These are the changes since Teensyduino 1.20-rc1:

  • Add SPI Transactions
  • Add libraries Adafruit_CC3000, SPIFlash, RadioHead, FastLED
  • Revert Adafruit_ILI9341 to Adafruit's version (highly optimized version planned reappear with new name)
  • Libraries ported to use SPI transactions: SD, Ethernet, Adafruit_CC3000, Adafruit_ILI9341, Adafruit_STMPE610, RadioHead
  • rename Serial1.availableForWrite() to writeBufferFree()
  • Add Czech keyboard layout to menu
  • Add yield() function on Teensy 2.0
 
Revert Adafruit_ILI9341 to Adafruit's version (highly optimized version planned reappear with new name)
Yep - I installed and my test case no longer compiles.

Looks like I need to either rename mine or not install yours...

Took a quick look through your updates, and I wonder how best to proceed with the optimized version. That is I believe the Transaction stuff mainly sets SPCR and SPSR registers, but I know from my hacking with how the SPI library as used by STMPE610 mucked up at least one of the IO pins, plus CTAR0, but I don't think it actually touched the CTAR1, which was defined to do some 16 bit spi transfers.

Suggestions? Punt for now? Continue with my own register swapping...

Thanks
Kurt
P.S - should I take this to different thread?
 
SPI transactions are out of neonatal care and to be released in .20?

Yes.

Yep - I installed and my test case no longer compiles.

Looks like I need to either rename mine or not install yours...

...

P.S - should I take this to different thread?

Let's start a new thread, just about this library. I want to do much, much more optimization that will take the library structure far away from Adafruit's design original.
 
If you were to use the RadioHead library, that library is among those altered for the SPI Transaction Library, and it has the Nordic module in the list. I presume that means it applies to all the radio types that are in RadioHead's suite, that use SPI.
 
If you were to use the RadioHead library, that library is among those altered for the SPI Transaction Library, and it has the Nordic module in the list. I presume that means it applies to all the radio types that are in RadioHead's suite, that use SPI.

Thanks, I'll take a look.
 
I just submitted the code as a pull request to Arduino. It took me a while to test and fix the problems on Arduino Due.

So far, I've patched 7 libraries: CC3000, ILI9341, STMPE610, RadioHead, SPIFlash, Ethernet and SD. Adafruit merged the changes, since I've been working with them throughout this lengthy SPI transaction project. Mike and Felix haven't, and probably won't have any interest until Arduino merges these or publishes 1.5.8 with SPI transactions.

I'm going to take a little break from this SPI stuff for a few days, until Cristian merges the SPI library and Ethernet & SD. Once the code is officially in the 1.5.x branch and there's at least one nightly build with the new code, it'll be much easier to talk with authors of other libraries about accepting patches.
 
To clarify, the SPI transaction manager changes to libraries like RadioHead retain the means to use those libraries but not call the Transaction manager functionality, right?
(backwards compatible)
 
To clarify, the SPI transaction manager changes to libraries like RadioHead retain the means to use those libraries but not call the Transaction manager functionality, right?
(backwards compatible)

The patches have "#if defined(SPI_HAS_TRANSACTION)", so the new stuff is used when compiled with the new SPI library, and everything is as it was when using the old version.

RadioHead has an abstraction layer built around the traditional SPI library. My patches for RadioHead add the new stuff in a kludgey way. When Arduino merges this SPI transaction stuff, I'm hoping Mike will consider adapting his abstraction layer. That's a much bigger change to his library than I feel comfortable attempting.
 
OK, thanks.

I have RadioHead within this two-way wireless bulk data transfer via low cost wireless, that I'm testing. Currently, there's no time-overlapped radio SPI and SPI Flash chip I/O.
I could code something (using Transactions) to force it to happen (say, an SPI flash chip read while I know the radio is sending or receiving), and see if errors occur as they should, and if Transactions cure it.

But first I need to try to cause/reproduce the RFM69 clocking with radio interrupt pending issue you reported. I spoke with Semtech (chip source) and Erik, their very knowledgeable engineer says there's been no reports of this but he doesn't know what timing might exist in fielded systems; just no reports of issues. He said he'd search for errata on this. They have shipped in quantities for 7 years, he says.

So I'll try to reproduce this with the software environment I have - which is:
Python GUI program on Windows/Linux/Mac computer. RadioHead protocol stack on that computer (my Python versions of RH). Addressed datagrams from PC to wireless gateway connected by serial link to computer.
Gateway bridges packets to/from wireless network and the serial port to the computer. No change in protocol; computer has network address.
End-node receives packets, ACKs each and when enough small packets have come in, it writes the cumulative data to SPI flash. The radio is made dormant during this SPI flash write (hundreds of bytes sent). But I could cause radio activity, e.g., have it transmit something while the SPI flash chip transfers are happening.
After writing flash, end node transmits "ACCEPTED" as it does for every packet. Gateway ACKs that and bridges the packet to the comptuer who then sends the next packet of data.
This goes on for 4500 bytes in my test case. (Binary version of a 12KB .hex file; can store any kind of file- 16MB of flash).
At the end, a CRC16 compute/compare is done by reading the flash. So there's CRC per packet and CRC for the entire file, and lost packet detection too (packets' sequence numbers are checked).

I can also address the file data to the gateway's SPI flash chip rather than the end-node. In this case, there's no radio I/O. This is a proof-check for if there's data corruption across the wireless link.

will advise.
steve
 
Last edited:
So I'll try to reproduce this with the software environment I have - which is:

You could simply run the exact code I used on any Teensy 3.1 with a RFM69 connected, and view the messages in the Arduino Serial Monitor or any terminal emulator. If you have any Teensy 3.1 with a RFM69 connected, it should be a very quick and easy thing to try.

It's quite possible there was a mistake on my end. Please let me know if you find anything?
 
Paul
I have two T3.0 each with an Osh board and an RFM69. Just tested the pair.
In reproducing the test you're running- the client/server demo...
I cannot find that demo you posted late last week.

To get this running, is this what I must do? (I have to be able to revert to resume development work I'm doing).
1. Backup current Teensyduino folder
2. Install 1.20rc2
3. Backup current RadioHead library folder
4. Install PJRC's version of the above
5. Using Paul's version of the client/server demo, build and download to each Teensy 3.0 (one client, one server)
Test for anomalies.

steve

PS: does the current beta version of the SPI Transaction manager compiler for the Teensy 2 / AVR target?
 
I gave it one try. No success, due to unclear things...
I installed Teensyduino 1.20rc2. Not sure I have the right version of that. I took it from the link URL at the top of this thread.
I removed RH lib and replaced it with PJRC's RH lib.

You provided source to RH's example "client" for the server/client demo.
Since there's no server example provided by PJRC, I assume I'm to use the RH example.
Not sure if this is supposed to work on T3.0 rather than 3.1.
I could not get RH's Server code to initialize the RFM69 after the above changes. Error on both T3.0 and T3.1.
The PJRC client didn't initialize. I fiddled with both a while. Double checked for loose connections.
I likely haven't gotten the software environment the way PJRC/Paul has is setup. Lots of chance for error.

I tried my known-good ping-pong test program.
Compiler error with T3.0
Code:
RH_pingpong.cpp.o:In function `SPISettings::init_AlwaysInline(unsigned long, unsigned char, unsigned char)'
SPI.h:ctar_clock_table'
SPI.h:ctar_div_table'
RH_pingpong.cpp.o:In function `SPIClass::setClockDivider(unsigned char)'
SPI.h:setClockDivider_noInline(unsigned long)'
collect2.exe*:error: ld returned 1 exit status
Error creating .elf
Same code compiles w/no error in T3.1. Runs on T3.1 with PJRC lib. (meaning it initialized the radio properly.) This would not use any Transaction API calls, but I could add them.

The Serial Monitor in Arduino's IDE is useless for this kind of work. It doesn't auto-reconnect after a download or power cycle. With two boards in use (wireless nodes), a mere mortal can't keep two Arduino serial monitors going; on instance of the IDE seems to tell the other through a back channel to switch so they both try to use the same port.
Bray's terminal is a little better; it has auto-reconnect as an option.

The serial terminal program in VisualStudio/VisualMicro has none of these issues. Open 2,3,4 and they all run in nice paned windows. They all reconnect automatically when the port is again available.
So I was using that, but to accommodate, I used the wretched Arduino IDE to compile and upload.

Installing 1.20rc2 wiped out my boards.txt that has the benign options in it to let VisualMicro run without needed a custom project - it gets the info for a Teensy build from Boards.txt if it has the added option lines for Teensy. Of course, I used an older boards.txt after installing 1.20rc2. I have to assume 1.20 didn't change boards.txt.

After a glass of wine, I'll be able to try again, if some of the above can be sorted out and some clarifications come on how the environment is supposed to be setup, and if this is supposed to work with 3.0.
When resuming, I'll use radio boards on T3.1 only.

Edit: Over to you, kind sir.
 
Last edited:
I likely haven't gotten the software environment the way PJRC/Paul has is setup. Lots of chance for error.

Start with a freshly extracted copy of Arduino 1.0.5, and then install 1.20-rc2.

That's it. No need to get anything from GitHub. 1.20-rc2 has the new SPI lib and the patched copy of RadioHead. Then all you need to do is program RadioHead's rf69_server onto one board and my rf69_client_extra.ino onto the other.

If using the adaptor board from OSH Park, make sure pins 15 and 16 are properly specified, on both the client and server. It needs to look like this:

Code:
RH_RF69 rf69(15, 16);

If 15 and 16 aren't specified (as the rf69_server example), RadioHead will default to pin 10 for chip select and pin 0 for the interrupt signal. It should work fine if you've connected to those pins. If using the adaptor boards, it's pins 15 & 16.
 
This is just a note to say that we are working hard to synchronize the next OSC library release
to go with 1.20 and for those interested in helping with the
testing, please use the github version of the OSC library: https://github.com/CNMAT/OSC.

So far we haven't found any problems with the release candidate with the USB side testing. Now onto the Ethernet side...
 
Last edited:
I'd volunteer for testing Ethernet "stuff" on Teensy 3 and/or Teensy 3.1 with WIZ820io. Perhaps also Teesny ++2 with WIZ812mj. What are Ethernet related problems you'd want us to test for ?
 
I typed a very erudite status report... But it disappeared into the forum bit bucket. (just as well!).
I have T3.1's working now. Mine are 433MHz, not 900 as are yours.
They are exchanging packets client/server, with transaction API enabled, and with/without the simulated ethernet traffic (actually, it's just creating SPI traffic with the RFM69's interrupts deferred, which is the supposed problem). Headroom: don't need real ethernet, just any SPI clocking while radio has interrupt request true and does so for quite a while -rather than prompt ISR as is the more normal case).

I'll be doing testing and analysis.

steve
 
I'd volunteer for testing Ethernet "stuff" on Teensy 3 and/or Teensy 3.1 with WIZ820io. Perhaps also Teesny ++2 with WIZ812mj. What are Ethernet related problems you'd want us to test for ?

By the end of the week I will have sorted out a couple of stray issues and then I am interested in seeing the standard examples we include in the library exercised. I will also add an example or two that exercise the UDP packet size questions. This new release also has early code for OSC timestamps and some routines for time stamping basic ADC, digital read and touch read.
 
@stevech
I was responding to Adrian's request for help with testing OSC over Ethernet

@adrianfreed
Ok. Will rest the samples. but also I've got example code that I found on Yotam's initial OSC site before it got hosted on the CNMAT site. This reads pins etc. from a Teensy and shows it through TouchOSC on an iPhone or iPad. It also allows to set pins from the iPhone. I cleaned it up (threw out stuff that was not teensy related) and re-wrote a number of things. This works pretty sweet over my WiFi set-up.
 
Paul and others re the SPI Transactions in RC2...
RF69 radio issue: SPI Clocks (and/or other related) sent while radio has interrupt request true for a long time due to other use of SPI port...
Using two T3.1's

I got the same code Paul was using running and did reproduce the symptoms.
Next, I decided to simplify the test and observe effect.
I reorganized the looping of the code and put in timers that detected things that might hang, such as transmit complete, etc.
I gave the client and server a "from" address and a packet sequence number. Server=1, Client=2. These both show in my off-air sniffer which I use to see transmitted packets by sequence number and source address, e.g, did it get sent?
(this sniffer is just an RFM69 module with my sniffer code and display on serial).
I changed the modulation mode on the radios to about 9Kbps using a profile that I have found to be among the best of the 20 available. We know there are serious problems with these 20 and we're working on it.
This modulation mode, using this test, and ideal signal strengths, still showed about 3% packet error rate. I put printouts on each end to tally these errors and delay 5 seconds before resuming.
With this, we can know to ignore these errors for the testing goal we have here.
I can run this modified code and see no problems other than the packet error rate for quite some time, with the code to call SPI.beginTransaction() and competing SPI transfers disabled.
The 'scope shows the interrupts from the radio are as expected.

Then I recompile and run with the SPI.beginTransaction(), pin 10 chip select, BUT NO spi clocking transfers. Just the chip select on/off.
After running normally about 15 seconds, the messages stop being transmitted. The 'scope shows that the radio's interrupt request came on and stays on forever.
This doesn't happen unless the transaction manager API call is made.
Looking at my 'scope, I see that the interrupt from the radio is goes true. But the ISR isn't running because there are no radio chip selects. This suggests that somehow the external interrupt enable got left in the false state.
So then I commented out the digitalWrite(10,LOW) and its mate, and ran program. A delayMicroseconds() in lieu of SPI.transfer() calls.
I haven't gotten it to fail. This is without sending an SPI clocks in the test.

Speculation: The new SPI transactions code is is not handling an esoteric of the SPI chip properly. On the AVR, there's the gotcha that if pin 10 (SS) is ever made to be be an input while the SPI chip is enabled, and there is a LOW on that pin, then the SPI chip automatically changes to the SPI slave mode. This may be n/a to the problem, or n/a to the K20.

I have included some code grabs and screen grab. I can make a screen video, maybe narrated, and post that somewhere too.

Also, would it be moot or useful to try this same code with a pair of mega328P boards and the same RFM69 radios and SPI transaction manager code?

Steve

Image is 1800 pixels wide...
grab1.jpg
Code:
#include "server.h"
#include <SPI.h>
#include <RH_RF69.h>

// THIS IS THE CLIENT SIDE TEST CODE
///////////////////////////////////////

//  SPI traffic while radio's chip select is false. comment out to stop such traffic.
#define DO_OTHER_SPI_ACTIVITY 1 // boolean

#define RADIO_SS_PIN 15
#define RADIO_IRQ_PIN 16
// Below two items must be same in server code
#define FREQUENCY 433.0
//#define MODULATION_MODE RH_RF69::FSK_Rb19_2Fd19_2 // this is index 4 in table
#define MODULATION_MODE RH_RF69::FSK_Rb9_6Fd9_6 // this is index 3 in table

RH_RF69 rf69(RADIO_SS_PIN, RADIO_IRQ_PIN);

void setup() 
{
	pinMode(10, OUTPUT);
	digitalWrite(10, HIGH);
	pinMode(15, INPUT_PULLUP);
	delay(100);
	Serial.begin(9600);
	//while (!Serial) ;
	delay(3000);
	Serial.println("PRJC CLIENT RF69 & Ethernet Test Begin");
	if (!rf69.init()) {
		Serial.println("RF69 init failed");
		while (1);
	}
	// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
	// No encryption
	if (!rf69.setFrequency(FREQUENCY)) {
		Serial.println("RF69 setFrequency failed");
		while (1);
	}

	rf69.setModemConfig(MODULATION_MODE); // this one works OK 

	Serial.println("RF69 init ok");
	// If you are using a high power RF69, you *must* set a Tx power in the
	// range 14 to 20 like this:
	//rf69.setTxPower(14);
  	// The encryption key has to be the same as the one in the server
	//uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
	//	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
	
	//stevech rf69.setEncryptionKey(key);
	rf69.setThisAddress(2);
	rf69.setHeaderFrom(2);
	delay(100);
}


void loop()
{
	uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
	static elapsedMillis msec;
    static elapsedMillis testtimeout;
	int errCount = 0;
	int receiveTimeout;
	static uint8_t packetNumber;
	uint8_t data[] = "Client says Hello World!";

  while (1)  { // stay in this function for sake of local vars
	Serial.print(millis()/1000);Serial.print(" errCount:");Serial.print(errCount);
    Serial.print(" Sending to rf69_server, ID#");Serial.println(packetNumber);
	rf69.setHeaderId(packetNumber++);
	rf69.send(data, sizeof(data));
	rf69.waitPacketSent();
	msec = 0; // timer
	receiveTimeout = 200; // msec
	//rf69.available(); // TURN ON RECIVER NOW
	while (msec < receiveTimeout) {
#if DO_OTHER_SPI_ACTIVITY
		//SPI.beginTransaction(SPISettings(12000000ul, MSBFIRST, SPI_MODE0));
        SPI.beginTransaction(SPISettings(4000000ul, MSBFIRST, SPI_MODE0));		
        //digitalWrite(10, LOW);
		delayMicroseconds(10);
		////for (int i=0; i > 0; --i) // some transfers in a single chip select
		////	SPI.transfer(0x00);
		//digitalWrite(10, HIGH);
		SPI.endTransaction();
#endif
		if (rf69.available())  {
			uint8_t len = sizeof(buf);
			Serial.println("calling recv()");
			rf69.recv(buf, &len);
			if (len == 0)
				{++errCount;Serial.println("ERROR: len==0");delay(5000);break;}      
			Serial.print("Client got reply in ");Serial.print(msec);
			Serial.print(" ms, len=");Serial.println(len);
			msec = 0;
			break; // escape inner while loop
		} // available()
	} // while (msec...
	if (msec >= receiveTimeout)
		{ ++errCount;Serial.println("ERROR: response timeout");delay(5000);} 
	delay(250); // message rate delay
  } // while (1)
} //  loop()

Code:
// THIS IS THE SERVER SIDE CODE
/////////////////////////////////////////////
// rf69_server.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing server
// with the RH_RF69 class. RH_RF69 class does not provide for addressing or
// reliability, so you should only use RH_RF69  if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example rf69_client
// Demonstrates the use of AES encryption, setting the frequency and modem
// configuration.
// Tested on Moteino with RFM69 http://lowpowerlab.com/moteino/
// Tested on miniWireless with RFM69 www.anarduino.com/miniwireless

#include <SPI.h>
#include <RH_RF69.h>

#define RADIO_SS_PIN 15
#define RADIO_IRQ_PIN 16

// Below two items must be same in server code
#define FREQUENCY 433.0
//#define MODULATION_MODE RH_RF69::FSK_Rb19_2Fd19_2 // this is index 4 in table
#define MODULATION_MODE RH_RF69::FSK_Rb9_6Fd9_6 // this is index 3 in table


RH_RF69 rf69(RADIO_SS_PIN, RADIO_IRQ_PIN);
// Singleton instance of the radio driver


void setup() 
{
  Serial.begin(9600);
  delay(3000);
  Serial.println("Server calling init");
  rf69.init();
  Serial.println("here here");
     
    
  if (!rf69.init())  {
    Serial.println("init failed");
    while(1)
      ;
  }
  Serial.println("init returned OK");  

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
	if (!rf69.setFrequency(FREQUENCY)) {
		Serial.println("RF69 setFrequency failed");
		while (1)
			;
	}
  else
    Serial.println("setFrequency returned OK"); 
  
  rf69.setModemConfig(MODULATION_MODE); // this one works OK in 433MHz band. Leave other band to use default

  // If you are using a high power RF69, you *must* set a Tx power in the
  // range 14 to 20 like this:
  // rf69.setTxPower(14);

 // The encryption key has to be the same as the one in the client
  //uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  //                  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  //rf69.setEncryptionKey(key);
  
#if 0
  // For compat with RFM69 Struct_send
  rf69.setModemConfig(MODULATION_MODE);
  rf69.setPreambleLength(3);
  uint8_t syncwords[] = { 0x2d, 0x64 };
  rf69.setSyncWords(syncwords, sizeof(syncwords));
  rf69.setEncryptionKey((uint8_t*)"thisIsEncryptKey");
#endif
	rf69.setThisAddress(1);
	rf69.setHeaderFrom(1);
Serial.println("exiting setup");

}

void loop()
{
  static elapsedMillis msec = 0;
  static elapsedMillis testtimeout;
  static uint8_t packetNumber = 0;

  if (rf69.available())
  {
    msec = 0; // reset msg receipt timer
    // Should be a message for us now   
    uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if (rf69.recv(buf, &len))
    {
      Serial.print("received: ");Serial.println((char*)buf); 
      uint8_t data[] = "Hello from server";
	  rf69.setHeaderId(packetNumber);
	  rf69.send(data, sizeof(data));       // Send a reply
      testtimeout = 0;
      //rf69.waitPacketSent();
      while (rf69.mode() == RH_RF69::RHModeTx) // changes at TX complete interrupt
		if (testtimeout >= 500)
			{Serial.println("tx interrupt timeout");while(1) ; }
	  rf69.available(); // TURN RECEIVER ON quickly
	  Serial.print("Server Sent reply ID#");Serial.println(packetNumber);
	  packetNumber++;
    }
    else
      Serial.println("recv() returned 0");
  }
  else 
	if (msec >= 1000)  {
		msec = 0;
		Serial.print(millis()/1000);Serial.println(" waiting for client msg");
	}
}
 
Last edited:
Two attachments to this posting ...
client and server source code files (.ino for Arduino IDE).
The files are identical to the code in the posting above this one.
Can be used with Arduino's IDE, or other.
 

Attachments

  • client.ino
    3.3 KB · Views: 214
  • server.ino
    3.5 KB · Views: 196
I have installed Arduino 1.0.5-r2 and patches for iteaduino-lite.
Teensyduino installer would not recognize the Arduino installation. (Even running as administrator)
I have to start from scratch instaling Arduino-ide, teensyduino and iteaduino-lite patches. In this order.
 
I have installed Arduino 1.0.5-r2 and patches for iteaduino-lite.
Teensyduino installer would not recognize the Arduino installation. (Even running as administrator)
I have to start from scratch instaling Arduino-ide, teensyduino and iteaduino-lite patches. In this order.

The means iteaduino is changing things in the Arduino environment that Teensyduino is looking for. I personally would keep these two in two separate Arduino installations.
 
Status
Not open for further replies.
Back
Top