如何在ESP32上使用2个SPI设备,LoRa和SD卡?

时间:2019-08-11 22:32:56

标签: sd-card spi esp32 lora

尝试使用集成的OLED和附带的SD卡对Heltec ESP32 LoRa进行编码。

我已经使SD卡(CS 21)和LoRa(CS 18)都可以单独工作,但是当我尝试使它们同时在同一程序中工作时,

//
// Heltec 32 LoRa OLED (with SD Card)
//               ______________
//          Gnd |    |  USB|   | Gnd
//           5v |    | port|   |  5v
//          3v3 |    |_____|   | 3v3
//          Gnd |      ALL     |  36<-     <- : Input Only!
//           Rx |     GPIO     |  37<-
//           Tx |     3.3v     |  38<-
//          RST |   ________   |  39<-
//            0 |  |        |  |  34<-
//    (SCL)  22 |  |        |  |  35<-
// SPI MISO  19 |  |        |  |  32<-
//           23 |  |        |  |  33<-
//LoRa CS(HI)18 |  |        |  |  25  (LED)
// SPI SCK    5 |  |  OLED  |  |  26  LoRa IRQ
//OLED SCL   15 |  |        |  |  27  SPI MOSI
//            2 |  |        |  |  14  LoRa Rst
//OLED SCA    4 |  |        |  |  12
//           17 |  |________|  |  13
//OLED RST   16 |______________|  21  (SD_CS)
//

#include <mySD.h>        //  SD Card (VMA304)
#include "SSD1306.h"     //  OLED
#include <LoRa.h>        //  LoRa

File root;

//       OLED       Pin
#define  SDA          4   //  Serial Data
#define  SCL         15   //  Serial Clock
#define  oRST        16   //  Reset
#define  OLED_ADDR 0x3C   //  OLED display TWI address

SSD1306         display(OLED_ADDR, SDA, SCL);
//  OLED screen text rows:
#define  row1     0     //  y=0 is top row of size 1 text
#define  row2    10
#define  row3    20
#define  row4    30
#define  row5    40
#define  row6    50     //  row7 at 70 is too low

//  SPI port #2:  SD Card Adapter
#define  SD_CLK      5
#define  SD_MISO    19
#define  SD_MOSI    27
#define  SD_CS      21

//  SPI port:  LoRa (SX1278) 
//       LoRa      Pin
#define  LoRa_SCK    5
#define  LoRa_MISO  19
#define  LoRa_MOSI  27
#define  LoRa_CS    18
#define  LoRa_RST   14    //  LoRa_Reset
#define  DI0        26    //  LoRa_IRQ
#define  BAND    915E6    //  other freq: 433E6  // or ? LoRa f(MHz)

#define  Select    LOW   //  Low CS means that SPI device Selected
#define  DeSelect  HIGH  //  High CS means that SPI device Deselected

File     sessionFile;   //  SD card filenames are restricted to 8 characters + extension

int counter = 0;        //  count sent LoRa messages

/***********************************************************/
void setup(){  
  // set output pins
  pinMode(oRST,OUTPUT);
  pinMode(SD_CS,OUTPUT);
  pinMode(LoRa_CS,OUTPUT);
  digitalWrite(LoRa_CS, DeSelect);

  // set GPIO16 Low then High to Reset OLED
  digitalWrite(oRST, LOW);  
  delay(50);
  digitalWrite(oRST, HIGH);

  Serial.begin(115200);
  while(!Serial);                     //  wait to connect to computer

  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.clear();
  display.display();

  Serial.print("Initializing SD card...");
  digitalWrite(SD_CS, Select);    //  SELECT (Low) SD Card SPI
  if (!SD.begin( SD_CS, SD_MOSI, SD_MISO, SD_CLK )) {
    Serial.println("initialization failed!");
    //  now what?
  } else {
    Serial.println("initialization done.");
    display.drawString( 5,row1,"SD Card OK!" );
    display.display();
    delay(1000);
  }
  /* open "test.txt" for writing */
  root = SD.open("test.txt", FILE_WRITE);
  if (root) {
    root.println("Hello world!");
    root.flush();
    root.close();
  } else {    //  file open error
    Serial.println("error opening test.txt");
  }
  display.drawString( 5,row2,"Wrote in test.txt" );
  display.display();
  delay(100);
  /* after writing, then reopen the file and read it */
  root = SD.open("test.txt");
  if (root) {    /* read from the file to the end of it */
    while (root.available()) {  // read the file
      Serial.write(root.read());
    }
    root.close();
  } else {
    Serial.println("error opening test.txt");
  }
  display.drawString( 5,row3,"Read from test.txt" );
  display.display();
  delay(100);
  //  done testing the SD Card
  digitalWrite(SD_CS, DeSelect);    //  DESELECT (high) SD Card SPI
  SD.end();
  delay( 100 ); 

  //  now test the LoRa

  SPI.begin( LoRa_SCK, LoRa_MISO, LoRa_MOSI, LoRa_CS );

  LoRa.setPins( LoRa_CS, LoRa_RST, DI0 );
  digitalWrite(LoRa_CS, Select);   //  SELECT (low) LoRa SPI 
  Serial.println("LoRa Sender");
  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    display.drawString( 5, row4, "LoRa Init Failed!");
    display.display();
    // now what?
  } else {
    Serial.println("LoRa Initial OK!");
    display.drawString( 5, row4, "LoRa Initialized OK!");
    display.display();
    delay(1000);
  }
  Serial.println("Setup done!");
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);
  display.clear();
  display.setFont(ArialMT_Plain_16);
  display.drawString(3, 5, "Sending packet ");
  display.drawString(50, 30, String(counter));
  display.display();
  // send packets
  LoRa.beginPacket();
  LoRa.print("Hi. Sent packet #");
  LoRa.print(counter);
  LoRa.endPacket();
  counter++;
  delay(500);
}

我有一个LoRa接收器正在工作,以读取消息。使用上面发布的代码,SD卡即可使用。 LoRa表示正在传输消息,但接收者看不到它们,并且在收到4条消息后停止。

3 个答案:

答案 0 :(得分:0)

通过添加合适的电阻器,我也可以同时使用LoRa和SD卡。 SD卡CS需要1k欧姆至3.3v。 MISO引脚19需要1k欧姆至3.3v, 和GND的1k欧姆 并在SD卡MISO引脚上加上100欧姆。

//OLED RST   16 |______________|  21  (SD_CS), w/1k ohm to 3.3v
//           RESISTORS ARE IMPORTANT
// SPI MISO needs 1k ohm to 3.3v, 1k ohm to GND, 100 ohm to SD MISO.

设置完之后,在loop()中:

void loop() {
  //  use the LoRa
  SPI.begin( LoRa_SCK, LoRa_MISO, LoRa_MOSI, LoRa_CS );
  LoRa.setPins( LoRa_CS, LoRa_RST, DI0 );
  digitalWrite(SD_CS, DeSelect);    //  deselet SD Card SPI
  digitalWrite(LoRa_CS, Select);    //  SELECT (low) LoRa SPI 
  if( LoRa.begin(BAND)) {

LoRa活动。然后...

    SPI.end();
  }
  if (!SD.begin( SD_CS, SD_MOSI, SD_MISO, SD_CLK )) {

SD卡活动,以...结束loop()

    //  done using the SD Card
    digitalWrite(SD_CS, DeSelect);    //  DESELECT (high) SD Card SPI
    SD.end();

这可能没有进行优化,但是有效!是的!

答案 1 :(得分:0)

如果使用Heltec WIFI LoRa 32(v2),最好将SD卡SCK放在36,39针上。 Vext Control使用了21。

答案 2 :(得分:0)

您只需要控制每个设备的芯片选择引脚,对于 无效,低电平表示有效,并且不能同时激活。