Как контролировать несколько SPI - PullRequest
0 голосов
/ 22 марта 2020

У меня проблемы с платой SAMD21. У меня есть этот стартовый набор (схемы), и я хочу добавить еще несколько датчиков. Они используют SPI, поэтому я их запрограммировал. Так как SAMD21 получает код, он запаздывает каждый раз, когда код реагирует на функцию начала сенсора. Пожалуйста, дайте мне несколько советов, как правильно контролировать оба SPI и избегать лагов.

* лаги - это общие лаги - SAMD21 ничего не делает после достижения функции начала.

* схемы: http://kit.sciencein.cz/wiki/images/b/be/MainBoard_v2.0_RevB_SCH.png

* извините за ошибки в коде (длинный код сокращен до короткого)

* мой код:

#include <Adafruit_BME280.h>  // include Adafruit BME280 library
  #include <Adafruit_INA219.h>  // include INA219
  #include <SD.h>          // include Arduino SD library
  #include "Open_Cansat_GPS.h"

  //include our new sensors
  #include "MQ131.h"

  #include <Wire.h>
  #include <SPI.h>

  #include "RFM69.h"       // include RFM69 library

  // Local
  #define PC_BAUDRATE       115200
  #define MS_DELAY    0  // Number of milliseconds between data sending and LED signalization
  #define LED_DELAY     100
  #define Serial SerialUSB
  RTCZero rtc;

  // RFM69
  #define NETWORKID       0        // Must be the same for all nodes (0 to 255)
  #define MYNODEID        1          // My node ID (0 to 255)
  #define TONODEID        2          // Destination node ID (0 to 254, 255 = broadcast)
  #define FREQUENCY       RF69_433MHZ   // Frequency set up
  #define FREQUENCYSPECIFIC 433000000  // Should be value in Hz, now 433 Mhz will be set
  #define CHIP_SELECT_PIN   43 //radio chip select
  #define INTERUP_PIN       9 //radio interrupt

  // BME280 SETTING
  #define BME280_ADDRESS_OPEN_CANSAT 0x77
  #define SEALEVELPRESSURE_HPA    1013.25

  //OZONE2CLICK
  const byte pinSS = 2; //cs pin
  const byte pinRDY = 12;
  const byte pinSCK = 13;
  const byte O2Pin = 10;
  #define DcPin 8

  // SD card
  #define sd_cs_pin 35 // set SD's chip select pin (according to the circuit)

  // create object 'rf69' from the library, which will
  // be used to access the library methods by a dot notation
  RFM69 radio(CHIP_SELECT_PIN, INTERUP_PIN, true);

  // define our own struct data type with variables; used to send data
  typedef struct
  {
    int16_t messageId;
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
    uint8_t sec;
    float longitude;
    float latitude;
    uint8_t num_of_satelites;
    float temperature;
    float pressure;
    float altitude;
    float humidity_bme280;
    float voltage_shunt;
    float voltage_bus;
    float current_mA;
    float voltage_load;
    int16_t rssi;
  } messageOut;

  messageOut cansatdata; //create the struct variable

  // create object 'bme' from the library, which will
  // be used to access the library methods by a dot notation
  Adafruit_BME280 bme;

  // create object 'ina219' from the library with address 0x40
  // (according to the circuit, which will be used to access the
  // library methods by a dot notation
  Adafruit_INA219 ina219(0x40);

  // create object 'gps' from the library
  OpenCansatGPS gps;

  // SD card 
  File file; // SD library variable

  // LEDS
  #define D13_led_pin 42  // D13 LED
  #define M_led_pin 36  // MLED

  // Local variables
  int idCounter = 1;
  bool isBmeOk = true;
  bool isSdOk = true;
  bool isRadioOk = true;
  bool isGpsConnected = true;

  // My variables
  float NH3Data;
  float COData;
  float NO2Data;
  float PPMO2;
  float PPBO2;
  float MGM3O2;
  float UGM3O2;
  float SSmoke1;
  float SSmoke2;
  float SSmoke3; 
  float ESmoke1;
  float ESmoke2;
  float ESmoke3;
  int DataCounter = 0;


  void OZONE2CLICKCalibrate ()
  {
  Serial.println("2");
    //MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000);  //(int _pinCS, int _pinRDY, int _pinPower, MQ131Model _model, int _RL)
    Serial.println("99");
    Serial.println("Calibration in progress...");

    MQ131.calibrate();

    Serial.println("Calibration done!");
    Serial.print("R0 = ");
    Serial.print(MQ131.getR0());
    Serial.println(" Ohms");
    Serial.print("Time to heat = ");
    Serial.print(MQ131.getTimeToRead());
    Serial.println(" s");
    }

  void OZONE2CLICKMeasure ()
  {
    Serial.println("Sampling...");
    MQ131.sample();
    Serial.print("Concentration O3 : ");
    PPMO2 = MQ131.getO3(PPM);
    Serial.print(PPMO2);
    Serial.println(" ppm");
    Serial.print("Concentration O3 : ");
    PPBO2 = MQ131.getO3(PPB);
    Serial.print(PPBO2);
    Serial.println(" ppb");
    Serial.print("Concentration O3 : ");
    MGM3O2 = MQ131.getO3(MG_M3);
    Serial.print(MGM3O2);
    Serial.println(" mg/m3");
    Serial.print("Concentration O3 : ");
    UGM3O2 = MQ131.getO3(UG_M3);
    Serial.print(UGM3O2);
    Serial.println(" ug/m3");
  }



  void setup()
  {
    pinMode(pinSS, OUTPUT);
    digitalWrite(pinSS, HIGH);
    delay(10000);
    Serial.begin(PC_BAUDRATE);

    // wait for the Arduino serial (on your PC) to connect
    // please, open the Arduino serial console (right top corner)
    // note that the port may change after uploading the sketch
    // COMMENT OUT FOR USAGE WITHOUT A PC!
    // while(!Serial);

    Serial.println("openCanSat PRO");

    Serial.print("Node ");
    Serial.print(MYNODEID,DEC);
    Serial.println(" ready");

    // begin communication with the BME280 on the previously specified address
    // print an error to the serial in case the sensor is not found
    if (!bme.begin(BME280_ADDRESS_OPEN_CANSAT))
    {
      isBmeOk = false;
      Serial.println("Could not find a valid BME280 sensor, check wiring!");
      return;
    }

    // begin communication with the INA219
    ina219.begin();

    // check of Gps is connected
    Wire.beginTransmission(0x42); // 42 is addres of GPS
    int error = Wire.endTransmission();

    if (error != 0)
    {
      isGpsConnected = false;
    }

    // begin communication with gps
    gps.begin();

    // Uncomment when you want to see debug prints from GPS library
    // gps.debugPrintOn(57600);

    if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
    {
      isRadioOk = false;
      Serial.println("RFM69HW initialization failed!");
    }
    else
    {
      radio.setFrequency(FREQUENCYSPECIFIC);
      radio.setHighPower(true); // Always use this for RFM69HW
    }

    pinMode(D13_led_pin, OUTPUT);
    pinMode(DcPin, OUTPUT);
    pinMode(MICS6814Pin, OUTPUT);
    pinMode(MICSVZ89TEPin, OUTPUT);
    pinMode(O2Pin, OUTPUT);
    GyroscopeTurnOn();
  }

  void loop()
  {
    cansatdata.messageId = idCounter;
    GyroscopeMeasure();
    LandingChecker();    

    Serial.println("MessageId = " + static_cast<String>(cansatdata.messageId));

    cansatdata.temperature = 0;
    cansatdata.pressure = 0;
    cansatdata.altitude = 0;

    if(isBmeOk)
    {
      cansatdata.temperature += bme.readTemperature();
      cansatdata.pressure += bme.readPressure() / 100.0F;
      cansatdata.altitude += bme.readAltitude(SEALEVELPRESSURE_HPA);
      cansatdata.humidity_bme280 = bme.readHumidity();
    }

    Serial.println("Temperature = " + static_cast<String>(cansatdata.temperature) + " *C");
    Serial.println("Pressure = " + static_cast<String>(cansatdata.pressure) + " Pa");
    Serial.println("Approx altitude = " + static_cast<String>(cansatdata.altitude) + " m");
    Serial.println("Humidity = " + static_cast<String>(cansatdata.humidity_bme280) + " %");

    // read values from INA219 into structure
    cansatdata.voltage_shunt = ina219.getShuntVoltage_mV();
    cansatdata.voltage_bus = ina219.getBusVoltage_V();
    cansatdata.current_mA = ina219.getCurrent_mA();
    cansatdata.voltage_load = cansatdata.voltage_bus + (cansatdata.voltage_shunt / 1000);

    Serial.println("Shunt Voltage: " + static_cast<String>(cansatdata.voltage_shunt) + " mV");
    Serial.println("Bus Voltage: " + static_cast<String>(cansatdata.voltage_bus) + " V");
    Serial.println("Current: " + static_cast<String>(cansatdata.current_mA) + " mA");
    Serial.println("Load Voltage: " + static_cast<String>(cansatdata.voltage_load) + " V");

    // Initialize GPS
    cansatdata.year = 0;
    cansatdata.month = 0  ;
    cansatdata.day = 0;
    cansatdata.hour = 0;
    cansatdata.minute = 0;
    cansatdata.sec = 0;
    cansatdata.latitude = 0;
    cansatdata.longitude = 0;
    cansatdata.num_of_satelites = 0;

    // save start time in millisec
    uint32_t start = millis();

    // END LED BLINK
    digitalWrite(D13_led_pin, LOW);


    pinMode(M_led_pin, INPUT);
    // END LED BLINK

    if(isGpsConnected)
    {
      if (gps.scan(250))
      {
        cansatdata.year = gps.getYear();
        cansatdata.month = gps.getMonth();
        cansatdata.day = gps.getDay();
        cansatdata.hour = gps.getHour();
        cansatdata.minute = gps.getMinute();
        cansatdata.sec = gps.getSecond();
        cansatdata.latitude = gps.getLat();
        cansatdata.longitude = gps.getLon();
        cansatdata.num_of_satelites = gps.getNumberOfSatellites();
        Serial.println(String("Time to find fix: ") + (millis() - start) + String("ms"));
        Serial.println(String("Datetime: ") + String(cansatdata.year) + "/"+ String(cansatdata.month) + "/"+ String(cansatdata.day) + " " + String(cansatdata.hour) + ":"+ String(cansatdata.minute) + ":"+ String(cansatdata.sec));
        Serial.println(String("Lat: ") + String(cansatdata.latitude, 7));
        Serial.println(String("Lon: ") + String(cansatdata.longitude, 7));
        Serial.println(String("Num of sats: ") + String(cansatdata.num_of_satelites));
        Serial.println();
      }
      else
      {
        Serial.println("Gps have no satelit to fix.");
      }
    }

    // RFM69HW
    cansatdata.rssi = 0;

    if(isRadioOk)
    {
      cansatdata.rssi = radio.RSSI;
      Serial.println("Signal = " + static_cast<String>(radio.RSSI));

      radio.send(TONODEID, (const void*)&cansatdata, sizeof(cansatdata));
    }

    Serial.println();

    // START LED hart beat
    pinMode(M_led_pin, OUTPUT);

    digitalWrite(D13_led_pin, HIGH);

    digitalWrite(M_led_pin, HIGH);
    // START LED hart beat

    if(!isGpsConnected)
    {
    delay(200);
    }

    idCounter ++;

  }
...