Teensy 3.2 + Audio Board + RFM69 Module: SPI Pin availability

althear

New member
I'm using a Teensy 3.2 with an audio board (with the SD Card) and would like to add an RFM69 module to it.

Looking at the audio board page, it seems pins 7 (MOSI), 10 (SS), 12 (MISO), 14 (SCK) are taken by the SD card.

The RFM Module needs to use those too, so I was planning on:
O (MISO) - 8
I (MOSI) - 11
C (SCK ) - 13
S (SS) - can be any digital pin?

The SPI page says I can change between alternate and original pins with
SPI.setSCK(RFM69_SCK);
SPI.setMOSI(RFM69_MOSI);
SPI.setMISO(RFM69_MISO);

When I check the audio board to see if pins 8,11,13 are used by it, it seems like 11 and 13 are taken too by the audio data. Does this mean I can't use the audio board and rfm69 modules together? I feel like I am misunderstanding something :(
 
Wire the RFM69 module like this: 7 (MOSI), 12 (MISO), 14 (SCK) and then use a different pin for SS (CS) - try pin 4. When pin 10 is asserted, the audio board's SD card will use pins 7, 12 14. When instead you assert pin 4, the Audio SD card won't listen and the RFM69 will.

Pete
 
Does that mean that i can never have both the audio and rfm69 module running at the same time? They will always be in conflict with that wiring? I followed that wiring and can activate them separately (thanks!), but if I wanted to have them run concurrently how would I do that?

I have background music running on the audio module and also want to transmit data on the rfm module while a button is pressed. (Sorry, my understanding of SPI is very basic). If I de-assert audio (10) when a button is pressed, then assert the rdm (4), would that essentially stop the music?

I'm looking up how to de-assert audio/pin 10, but would it basically be following the transaction section in https://www.pjrc.com/teensy/td_libs_SPI.html


Edit:
additional question: I can't have two sets of MOSI, SCK, and, MISO pins running at the same time, right?
 
The SPI pins are only used for the SD card (and memory chip, if present) so you can use the SD card while running audio. (The audio board is controlled using the I2C pins 18 and 19)

The T3.2 only has one SPI controller which limits you to only one SPI device active at a time. Some other Teensies have more than one controller. See the specifications of the various Teensys here.

Pete
 
I'm trying to work out transactions with the RFM69 and Audio shield. The idea is to have music playing in the background, but when a button is pressed the radio will take over momentarily to send data and then give control back to the audio.

Trying to make the code be as simple as possible so I can debug, but it seems I don't know how to do the setup. As soon as I call sd.begin and manager.init (not sure if SPI.begin too anymore), the speaker goes crazy with a static buzz. How do I setup the audio and radio together?

This is my first time with transactions, am I calling the transactions correctly? haven't been able to get passed the setup yet :(


//-----------------------------INCLUDES------------------------------//
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <RH_RF69.h>
#include <RHReliableDatagram.h>

//-----------------------------AUDIO------------------------------//
AudioPlaySdWav playSdWav1;
AudioOutputI2S audioOutput;
AudioConnection patchCord1(playSdWav1, 0, audioOutput, 0);
AudioConnection patchCord2(playSdWav1, 1, audioOutput, 1);
AudioControlSGTL5000 sgtl5000_1;

// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14

//-----------------------------RADIO------------------------------//
#define RFM69_MISO 12
#define RFM69_RST 5
#define RFM69_CS 17
#define RFM69_INT digitalPinToInterrupt(0) // only pins 0, 1, 2 allowed

#define CLIENT_ADDRESS 1 // Sender
#define SERVER_ADDRESS 2 // Receiver

// Change to 434.0 or other frequency, must match RX's freq!
#define RF69_FREQ 915.0

// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT); // For RF69 on PJRC breakout board with Teensy 3.1

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(rf69, SERVER_ADDRESS);

//Radio Data
int16_t packetnum = 999; // packet counter, we increment per xmission
int16_t currentOrder = 999;
int16_t oldOrder = 999;
uint8_t data[] = "Hello World!";
uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];

//------------------------SPI TRANSACTIONS------------------------------//
// using two incompatible SPI devices, SD Card Audio and RFM69 Radio
const int slaveAudioPin = SDCARD_CS_PIN;
const int slaveRadioPin = RFM69_CS;

// set up the speed, mode and endianness of each device
SPISettings settingsAudio(2000000, MSBFIRST, SPI_MODE1);
SPISettings settingsRadio(2000000, MSBFIRST, SPI_MODE1);

//---------------------------------SETUP------------------------------//
void setup() {
Serial.begin(9600);

// SPI
pinMode (slaveAudioPin, OUTPUT);
pinMode (slaveRadioPin, OUTPUT);
SPI.begin();

//AUDIO
AudioMemory(8);
sgtl5000_1.enable();
sgtl5000_1.volume(0.45);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);

// if (!(SD.begin(SDCARD_CS_PIN))) {
// while (1) {
// Serial.println("Unable to access the SD card");
// delay(500);
// }
// }

// RADIO
//For Teensy 3.x and T4.x the following format is required to operate correctly
//pinMode(LED, OUTPUT);
pinMode(RFM69_RST, OUTPUT);
digitalWrite(RFM69_RST, LOW);

// manual reset
digitalWrite(RFM69_RST, HIGH);
delay(10);
digitalWrite(RFM69_RST, LOW);
delay(10);

if (!manager.init()) {
Serial.println("RFM69 radio init failed");
while (1);
}

Serial.println("RFM69 radio init OK!");

// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
// No encryption
if (!rf69.setFrequency(RF69_FREQ)) {
Serial.println("setFrequency failed");
}

// If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
// ishighpowermodule flag set like this:
rf69.setTxPower(20); // range from 14-20 for power, 2nd arg must be true for 69HCW
Serial.print("RFM69 radio @"); Serial.print((int)RF69_FREQ); Serial.println(" MHz");

delay(1000);
}


void loop() {

if (playSdWav1.isPlaying() == false) {
Serial.println("Start playing");
playSdWav1.play("SDTEST3.WAV");
delay(10); // wait for library to parse WAV info
}

//if (newData()){
// New data to send detected, so we must open up the SPI for
// the radio (de-assert SD Pin 10, assert radio pin, send data, deassert radio, assert SD)
SPI.beginTransaction(settingsRadio); //Begin talking to radio and pause SD SPI connection
digitalWrite (slaveRadioPin, LOW); // Do I need this?
sendDataPacket();
digitalWrite (slaveRadioPin, HIGH); // Do I need this?
SPI.endTransaction();
//}
}

void sendDataPacket() {
char radiopacket[20] = "Hello World #";
int16_t packetnum = 0;
itoa(packetnum, radiopacket, 10);
//Serial.print("Sending ");
Serial.println(radiopacket);

// Send a message to manager_server
if (manager.sendtoWait(radiopacket, sizeof(radiopacket), SERVER_ADDRESS)) {
// Now wait for a reply from the server
uint8_t len = sizeof(buf);
uint8_t from;
if (manager.recvfromAckTimeout(buf, &len, 2000, &from)) {
Serial.println((char*)buf);
} else {
Serial.println("No reply, is rf69_reliable_datagram_server running?");
}
}
}
 
Back
Top