Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: Using SPI1 or SPI2 in Radiohead library

  1. #1
    Member
    Join Date
    Mar 2019
    Location
    Sweden
    Posts
    28

    Using SPI1 or SPI2 in Radiohead library

    Hi,

    I would like to use SPI1 or SPI2 together with Radioheads RH_RF69 library to avoid my hanging problems.
    How do I setup my code to do that?
    Do I have to change something in the library code?

    I'm using T3.5 or T4.0

    Grateful for help.

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,414
    It has been awhile since I did it, but there is some support for this at least in the Teensyduino installed version.

    I played with this a few years ago. Note I am am using RF95, but assume would be the same... And I did it on SPI1, but did add it for SPI2 as well.

    In my sketch I had:
    Code:
    #include <RHDatagram.h>
    #include <RH_RF95.h>
    #include <RHHardwareSPI1.h>
    ...
    RH_RF95 rf95(RFM95_CS, RFM95_INT, hardware_spi1);
    
    // Class to manage message delivery and receipt, using the driver declared above
    RHDatagram manager(rf95, WM_MASTER_NODE);
    Edit:
    I also note I may not have used standard SPI1 pins so my code also had:
    Code:
    SPI1.setMISO(RFM95_MISO);
      SPI1.setMOSI(RFM95_MOSI);
      SPI1.setSCK(RFM95_SCK);
    And I ran this on T3.5 or T3.6 but I believe I also tested it later on T4

  3. #3
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,553
    Just taking a quick look at the examples and the lib for the RH_RF69 looks like you can specify SPI1 or SPI1 (default is SPI). For instance, from the rf69_tx_demo.ino in the Teensy example folder:
    Code:
    //For Teensy 3.x and T4.x the following format is required to operate correctly
    //This is a limitation of the RadioHead radio drivers
    #define RFM69_RST     3
    #define RFM69_CS      10
    #define RFM69_INT     digitalPinToInterrupt(2)
    
    // Singleton instance of the radio driver
    RH_RF69 rf69(RFM69_CS,RFM69_INT);
    . This is setting up the lib to use SPI but from the library RH_RF69.h the constructor has another element you can specify (the SPI port):
    Code:
        /// \param[in] spi Pointer to the SPI interface object to use. 
        ///                Defaults to the standard Arduino hardware SPI interface
        RH_RF69(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, RHGenericSPI& spi = hardware_spi);
    so if you want to use SPI1 say with out example:

    Code:
    //For Teensy 3.x and T4.x the following format is required to operate correctly
    //This is a limitation of the RadioHead radio drivers
    #define RFM69_RST     3
    #define RFM69_CS      10
    #define RFM69_INT     digitalPinToInterrupt(2)
    
    #include <RHHardwareSPI1.h>
    
    // Singleton instance of the radio driver
    RH_RF69 rf69(RFM69_CS,RFM69_INT, hardware_spi1);
    The changes are highlighted in red. First you need to include the driver:
    Code:
    #include <RHHardwareSPI1.h
    then update the constructor to tell it to use spi1:
    Code:
    RH_RF69 rf69(RFM69_CS,RFM69_INT, hardware_spi1);

  4. #4
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,553
    @KurtE
    Looks like we cross posted

  5. #5
    Member
    Join Date
    Mar 2019
    Location
    Sweden
    Posts
    28
    I have tested with your suggestions on Teensy 3.5
    The setup works OK with normal SPI on pins 10,11,12,13

    I have skifted to pins: 0,1,31,32 according to T3.5 spec.


    #include <RH_RF69.h> //Radiohead
    #include <RHHardwareSPI1.h>

    #define RFM69_RST 24
    #define RFM69_CS 31
    #define RFM69_INT digitalPinToInterrupt(25)

    // Singleton instance of the radio driver
    RH_RF69 rf69(RFM69_CS,RFM69_INT,hardware_spi1);

    ....

    void setup() {
    Serial.begin(9600);

    delay(500);


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

    digitalWrite(RFM69_RST, LOW);
    delay(100);

    Serial.println("Midi interface med trådlös modul RFM69HCW!");

    digitalWrite(RFM69_RST, HIGH);
    delay(100);
    digitalWrite(RFM69_RST, LOW);
    delay(100);

    //SPI1.setMISO(1);
    //SPI1.setMOSI(0);
    //SPI1.setSCK(32);

    if (!rf69.init())
    Serial.println("init failed");
    // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
    // No encryption
    if (!rf69.setFrequency(868.0))
    Serial.println("setFrequency failed");

    // 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);
    //rf69.setEncryptionKey((uint8_t*)ENCRYPTKEY);


    Unfortunately I get "init failed"

    Is there a way of testing?

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,414
    Maybe try SPI1.begin();
    Just before the call to the rf69.init?

    Otherwise maybe need to add debug code to the init function and find out where it is failing.

  7. #7
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,553
    Found my RF69HCW radio from Adafruit (https://www.adafruit.com/product/3070) and ran the sketch the modified rf69_tx_demo sketch that I mentioned but configured for SPI and I can't seem to duplicate your error about not initializing the radio:
    Code:
    RFM69 radio init OK!
    RFM69 radio @434 MHz
    Sending Hello World #0
    No reply, is another RFM69 listening?
    The radio is initializing. I didn't hook up the receiving one that is why the no reply message. Below is the exact sketch I am using. Would start by checking your wiring - maybe you have MISO/MOSI backwards - I have done that a number of times

    Code:
    // rf69 demo tx rx.pde
    // -*- mode: C++ -*-
    // Example sketch showing how to create a simple messageing client
    // 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_server.
    // Demonstrates the use of AES encryption, setting the frequency and modem 
    // configuration
    
    #include <SPI.h>
    #include <RH_RF69.h>
    #include <RHHardwareSPI1.h>
    
    /************ Radio Setup ***************/
    
    // Change to 434.0 or other frequency, must match RX's freq!
    #define RF69_FREQ 434.0
    
    //For Teensy 3.x and T4.x the following format is required to operate correctly
    //This is a limitation of the RadioHead radio drivers
    #define RFM69_RST 24
    #define RFM69_CS 31
    #define RFM69_INT digitalPinToInterrupt(25)
    
    // Singleton instance of the radio driver
    RH_RF69 rf69(RFM69_CS,RFM69_INT, hardware_spi1);
    //----- END TEENSY CONFIG
    
    int16_t packetnum = 0;  // packet counter, we increment per xmission
    
    void setup() 
    {
      Serial.begin(115200);
      //while (!Serial) { delay(1); } // wait until serial console is open, remove if not tethered to computer
    
      //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);
    
      Serial.println("Feather RFM69 TX Test!");
      Serial.println();
    
      // manual reset
      digitalWrite(RFM69_RST, HIGH);
      delay(10);
      digitalWrite(RFM69_RST, LOW);
      delay(10);
      //----- END TEENSY CONFIG
    
      if (!rf69.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
    
      // 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};
      rf69.setEncryptionKey(key);
      
      //pinMode(LED, OUTPUT);
    
      Serial.print("RFM69 radio @");  Serial.print((int)RF69_FREQ);  Serial.println(" MHz");
    }
    
    
    
    void loop() {
      delay(1000);  // Wait 1 second between transmits, could also 'sleep' here!
    
      char radiopacket[20] = "Hello World #";
      itoa(packetnum++, radiopacket+13, 10);
      Serial.print("Sending "); Serial.println(radiopacket);
      
      // Send a message!
      rf69.send((uint8_t *)radiopacket, strlen(radiopacket));
      rf69.waitPacketSent();
    
      // Now wait for a reply
      uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
      uint8_t len = sizeof(buf);
    
      if (rf69.waitAvailableTimeout(500))  { 
        // Should be a reply message for us now   
        if (rf69.recv(buf, &len)) {
          Serial.print("Got a reply: ");
          Serial.println((char*)buf);
          //Blink(LED, 50, 3); //blink LED 3 times, 50ms between blinks
        } else {
          Serial.println("Receive failed");
        }
      } else {
        Serial.println("No reply, is another RFM69 listening?");
      }
    }
    
    void Blink(byte PIN, byte DELAY_MS, byte loops) {
      for (byte i=0; i<loops; i++)  {
        digitalWrite(PIN,HIGH);
        delay(DELAY_MS);
        digitalWrite(PIN,LOW);
        delay(DELAY_MS);
      }
    }

  8. #8
    Member
    Join Date
    Mar 2019
    Location
    Sweden
    Posts
    28
    No that did not help.
    I have started to debug the library with a LED.

    It fails in RHHardwareSPI1.cpp:

    uint8_t RHHardwareSPI1::transfer(uint8_t data)
    {
    return SPI1.transfer(data);
    }

    It's called from RHSPIdriver.cpp:

    uint8_t RHSPIDriver::spiRead(uint8_t reg)
    {
    uint8_t val;
    ATOMIC_BLOCK_START;
    _spi.beginTransaction();
    digitalWrite(_slaveSelectPin, LOW);
    _spi.transfer(reg & ~RH_SPI_WRITE_MASK); // Send the address with the write mask off
    val = _spi.transfer(0); // The written value is ignored, reg value is read
    digitalWrite(_slaveSelectPin, HIGH);
    _spi.endTransaction();
    ATOMIC_BLOCK_END;
    return val;
    }

    which is called from RH_RF69.cpp:

    _deviceType = spiRead(RH_RF69_REG_10_VERSION);
    if (_deviceType == 00 ||
    _deviceType == 0xff)
    return false;


    This returns 00

    Am I using the correct pins for SPI1?

    /Tomas

  9. #9
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,553
    The pins look correct but as I mentioned are hooked up correctly to the Teensy 3.5

    For SPI1:
    Code:
    sck -> pin 32 
    cs -> pin 31
    miso -> pin 1
    mosi -> pin 0
    then of course you have:
    Code:
    #define RFM69_RST 24
    #define RFM69_CS 31
    #define RFM69_INT digitalPinToInterrupt(25)

  10. #10
    Member
    Join Date
    Mar 2019
    Location
    Sweden
    Posts
    28
    Thanks for all your help.
    It was off cause my wireing that was the problem.
    It was not MOSI/MISO that was switched. I had mirrored the whole Teensy
    so 31 became 34 and so on. No wonder nothing worked.

    Now it's up and running.

  11. #11
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,553
    Quote Originally Posted by kets View Post
    Thanks for all your help.
    It was off cause my wireing that was the problem.
    It was not MOSI/MISO that was switched. I had mirrored the whole Teensy
    so 31 became 34 and so on. No wonder nothing worked.

    Now it's up and running.
    Cool glad thats all it was.

  12. #12
    Hi, I hope someone can help me out here. I need NRF24 on SPI1, because I have an ethernet on SPI.
    Below my code (simplified). From as soon as I add
    RH_NRF24 nrf24(4,5,hardware_spi1);
    I get tons of errors.
    When I use
    RH_NRF24 nrf24(4,5);
    All works fine, but that is on SPI.
    Other question, how do I add code in this forum in those nice boxes?
    Thanks in advance,
    Olivier

    Code:
    #include <SPI.h>
    #include <RH_NRF24.h>
    #include <RHHardwareSPI1.h>
    RH_NRF24 nrf24(4,5,hardware_spi1);  //  CE pin, CSN pin
    
    
    void setup() {
    	Serial.begin(115200);
      Serial.println("start");
      if (!nrf24.init())
        Serial.println("init failed");
      if (!nrf24.setChannel(110))
        Serial.println("setChannel failed");
      if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
        Serial.println("setRF failed"); 
    }
    
    
    void loop() {
    }
    Last edited by KurtE; 01-01-2023 at 03:26 PM. Reason: code tag

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,414
    Select the text and use the # button on toolbar... On other forums the button might look like <>

    Which teensy are you building for? Which Arduino version? Teensyduino version?

    What are the errors? I did a cut and paste, and it built for me, for T4.1

  14. #14
    Thanks for the quick reply. I found my problem, I was using the standard library for radiohead. Not the teensy RADIOHEAD-library.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •