Getting one Teensy 3.6 to act like 2 SPI slaves

Status
Not open for further replies.

bitofadummy

Member
Hello everybody,

I have a project that I need some guidance with.

The goal is to have a dual temperature controller for a 3D printer, but the sensor I am using is a Thermal Imaging Camera (MLX90641 16x12 IR Array with 110° FOV)
Teensy wil have to read the array, filter out two hotspots, and send these values over SPI to the 3D printer firmware.
As I am using Smoothieware, it can be configured to read two thermocouples over SPI, but instead of two max31855 sensorboards I will hook up one Teensy 3.6

After two weeks of "copy and pasting" it did get the SPI communication to work using the TSPIslave library by Tonton81 (many thanks for that!!).

But the way it works is a bit awkward:
I had to set up two seperate SPI busses (SPI0 and SPI1).
and I wired the MISO, MOSI and SCK lines by daisy chaining them to the 3D printer board.
Then the two cs lines are are wired directly to two seperate pins of the 3d printer board.

Then I am running this code:


PHP:
//source: https://github.com/tonton81/TSPISlave


#include "TSPISlave.h"

uint8_t miso0 = 12;  //miso en mosi lines must be crossed from the master!!
uint8_t miso1 = 1;
uint8_t mosi0 = 11;
uint8_t mosi1 = 0;
uint8_t sck0 = 14; 
uint8_t sck1 = 32;
uint8_t cs0 = 10;
uint8_t cs1 = 31;
uint8_t spimode = 16;
uint8_t i=0;
volatile uint16_t payloadfront;
volatile uint16_t payloadback;
volatile uint16_t receivedfront;
volatile uint16_t receivedback;
float tempfront=5;
float tempback=10;
uint16_t tempx4front;
uint16_t tempx4back;
//int led = 13;
//volatile byte ledstate = LOW;

TSPISlave mySPIfront = TSPISlave(SPI, miso0, mosi0, sck0, cs0, spimode);
TSPISlave mySPIback = TSPISlave(SPI1, miso1, mosi1, sck1, cs1, spimode);

void setup() {
 
 Serial.begin(115200);
  delay(500); 
  Serial.println("Start program");
//pinMode(led, OUTPUT);

//   digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
//  delay(1000);               // wait for a second
//  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
//  delay(200);               // wait for a second
//   digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 // delay(250);               // wait for a second
 // digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
//  delay(200);               // wait for a second
//   digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 // delay(50);               // wait for a second
 // digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 // delay(200);               // wait for a second

 mySPIfront.onReceive(myFuncfront);
 mySPIback.onReceive(myFuncback);


}

void loop() {
    
  if(tempfront>100){ tempfront=10;}
   if(tempback>100){ tempback=10;}
   
 tempfront= tempfront*1.1;
  tempback= tempback*1.05 ;
  
  tempx4front=tempfront*4;
    tempx4back=tempback*4;
    
   bitWrite(tempx4front, 16, 0);
   bitWrite(tempx4back, 16, 0);
      
  cli();
  payloadfront = tempx4front<<2;
  payloadback = tempx4back<<2;
  sei();
  
   
 // digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 //   delay(500);               // wait for a second
  //digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(200); 
  
  Serial.print("tempfront = ");
  Serial.println(tempfront);
  Serial.print("payloadfront = ");
  Serial.println(payloadfront, BIN);
 
  Serial.print("tempback = ");
  Serial.println(tempback);
  Serial.print("payloadback = ");
  Serial.println(payloadback, BIN);

 // digitalWrite(led, sensor);
 
}

void myFuncfront() {  
   while ( mySPIfront.active() ) {
    if (mySPIfront.available()) {
     mySPIfront.pushr(payloadfront);
      receivedfront=mySPIfront.popr();
  }
}
}

void myFuncback() { 
   while ( mySPIback.active() ) {
    if (mySPIback.available()) {
     mySPIback.pushr(payloadback);
      receivedback=mySPIback.popr();
   
 }
 }
 }



Now it works, but it takes up a lot of pins and wiring.

So my question is: is there a more simple methode to accomplisch the same thing?
 
You can usually put multiple slaves on one SPI bus and the CS pin will tell the slaves when they are being communicated with. I believe you should be able to get rid of one of your spi lines and set both slaves up on spi0 with two CS pins to cut down some of your wiring and pin usage. By daisy chaining do you mean soldering the corresponding spi0 and spi1 pins together?
 
Yes I now have a daisy chain that goes from MISO1 to MISO0 to MOSI on the printerboard (some how this library needs MISO to MOSI instead of MISO to MISO), and the same goes for MOSI and SCK..

I started out with two SPI setup lines like this:

TSPISlave mySPIfront = TSPISlave(SPI, miso, mosi, sck, cs0, spimode);
TSPISlave mySPIfront = TSPISlave(SPI, miso, mosi, sck, cs1, spimode);

So I Shared all the pins except the cs-lines
it would compile and upload, but teensy just locked up....
 
I think this depends on whether there are one or two masters

My master in this setup is the SKR 1.3 board with smoothieware, as it requests the temperature reedings.
And Teensy is running de TSPISlave library, there is not realy an option to accidentally set it up as a master like with an arduino nano using the SPI library from Nick Gammon ...
 
Status
Not open for further replies.
Back
Top