Проблема с SPI при использовании трансивера RF24 NRF24L01 со светодиодной матрицей MD_MAX72xx

В настоящее время я использую Arduino Mega для использования светодиодной матрицы и трансивера NRF24L01.

Для светодиодной матрицы я использую библиотеку MD_MAX72xx. А для трансивера я использую библиотеку RF24.

Я уже могу подключить Arduino, используя две разные светодиодные матрицы, а две матричные платы уже используют SPI.

Но когда я пытаюсь добавить библиотеку RF24, и radio.begin(); светодиодная матрица больше не работает должным образом.

Вот весь мой код:

#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Servo.h>

#include <nRF24L01.h>
#include <RF24.h>

#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }

#define BUF_SIZE      75  // размер текстового буфера
#define CHAR_SPACING  3   // пикселей между символами
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

const int buzzer_pin = 26;
const int servo_pin = 28;

unsigned long buzz_time;
unsigned long sys_time;
String buzz_type = "off";
int buzz_count = 0;
char charr[50];

Servo myservo;

RF24 radio(30, 32); // CE, ДНС
const byte address[6] = "GLN71";
//адрес константного байта[5] = {'R','x','A','A','A'};

struct LineDefinition
{
  MD_MAX72XX  mx;
  char    message[BUF_SIZE];
  boolean newMessageAvailable;    // true, если пришло новое сообщение
};

struct LineDefinition  Line[] =
{
  { MD_MAX72XX(HARDWARE_TYPE, 51, 52, 53, MAX_DEVICES), "MAX", true },
  { MD_MAX72XX(HARDWARE_TYPE, 51, 52,  49, MAX_DEVICES), "MAX", true }
};

#define MAX_LINES   (sizeof(Line)/sizeof(LineDefinition))

void printText(uint8_t lineID, uint8_t modStart, uint8_t modEnd, char *pMsg)
// Распечатываем текстовую строку в указанные модули светодиодной матрицы.
// Область сообщения после печати заполняется пустыми столбцами.
{
  uint8_t   state = 0;
  uint8_t   curLen;
  uint16_t  showLen;
  uint8_t   cBuf[8];
  int16_t   col = ((modEnd + 1) * COL_SIZE) - 1;

  Line[lineID].mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);

  do     // конечный автомат для печати символов в доступном пространстве
  {
    switch(state)
    {
      case 0: // Загружаем следующий символ из таблицы шрифтов
        // если мы достигли конца сообщения, сбрасываем указатель сообщения
        if (*pMsg == '\0')
        {
          showLen = col - (modEnd * COL_SIZE);  // символы заполнения
          state = 2;
          break;
        }

        // извлекаем следующий символ из файла шрифта
        showLen = Line[lineID].mx.getChar(*pMsg++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
        curLen = 0;
        state++;
        // !! намеренно перейти в следующее состояние, чтобы начать отображение

      case 1: // отображаем следующую часть символа
        Line[lineID].mx.setColumn(col--, cBuf[curLen++]);

        // закончили с символами шрифта, теперь отображаем пространство между символами
        if (curLen == showLen)
        {
          showLen = CHAR_SPACING;
          state = 2;
        }
        break;

      case 2: // инициализируем состояние для отображения пустых столбцов
        curLen = 0;
        state++;
        // Проваливаться

      case 3: // отображаем межсимвольный интервал или заполнение сообщения (пустые столбцы)
        Line[lineID].mx.setColumn(col--, 0);
        curLen++;
        if (curLen == showLen)
          state = 0;
        break;

      default:
        col = -1;   // это определенно завершает цикл do
    }
  } while (col >= (modStart * COL_SIZE));

  Line[lineID].mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
}

void buzz_start(){
    buzz_count = 5;
    buzz_time = millis();
}

void buzz_call(){
  if(buzz_count > 0){
    if(millis() >= buzz_time){
      if(buzz_type == "off"){
        tone(buzzer_pin, 1000);
        buzz_type = "on";
      }else{
        noTone(buzzer_pin);
        buzz_type = "off";
        buzz_count--;
      }
      buzz_time = millis() + 300;
    }
  }
}

void setup()
{
  Serial.begin(57600);
  pinMode(buzzer_pin, OUTPUT);

  myservo.attach(servo_pin);

  tone(buzzer_pin, 1000);
  Serial.println("BEGIN");





  for (uint8_t i=0; i<MAX_LINES; i++){
    Line[i].mx.begin();
  }

  radio.begin();
  radio.openReadingPipe(20, address);
  radio.setPALevel(RF24_250KBPS);
  radio.startListening();

  String charrr = "STOP";
  charrr.toCharArray(charr, 50);
  printText(1, 0, MAX_DEVICES-1, charr);

  myservo.write(90);
  delay(500);
  myservo.write(180);

  noTone(buzzer_pin);
  sys_time = millis();
}

int counter = 10;
int disp = 0;
void loop()
{
  String charrr = String(counter);
  charrr.toCharArray(charr, 50);
  printText(0, 0, MAX_DEVICES-1, charr);
  if(counter == 0){
    counter = 9;
    if(disp == 0){
     disp = 1; 
     String charrr = "  GO";
     charrr.toCharArray(charr, 50);
     printText(1, 0, MAX_DEVICES-1, charr);
     myservo.write(90);
     buzz_start();
    }else{
     disp = 0;
     String charrr = "STOP";
     charrr.toCharArray(charr, 50);
     printText(1, 0, MAX_DEVICES-1, charr);
     buzz_start();
     myservo.write(180);
    }
  }
  if(millis() >= sys_time){
    counter--;
    sys_time = millis() + 1000;  
  }

  buzz_call();

}

Думаю, проблема здесь не в соединении, а в инициализации RF24 и radio.begin();

, 👍0


1 ответ


Лучший ответ:

0

Я заглянул в исходный код библиотеки MD_MAX72XX. Конструктор с выводами SPI запускает программный SPI.

Используйте конструктор MD_MAX72XX::MD_MAX72XX(moduleType_t mod, uint8_t csPin, uint8_t numDevices): для работы с оборудованием/библиотекой SPI со всеми устройствами.

struct LineDefinition  Line[] =
{
  { MD_MAX72XX(HARDWARE_TYPE, 53, MAX_DEVICES), "MAX", true },
  { MD_MAX72XX(HARDWARE_TYPE, 49, MAX_DEVICES), "MAX", true }
}; 

Или, если MD_MAX72XX работал у вас с программным SPI, используйте другие контакты, а не контакты аппаратного SPI, чтобы освободить аппаратный SPI для NRF24L01.

struct LineDefinition  Line[] =
{
  { MD_MAX72XX(HARDWARE_TYPE, SW_SPI_SI, SW_SPI_CLK, MAX1_CS, MAX_DEVICES), "MAX", true },
  { MD_MAX72XX(HARDWARE_TYPE, SW_SPI_SI, SW_SPI_CLK, MAX2_CS, MAX_DEVICES), "MAX", true }
};
,

Вы предлагаете инициализировать трансивер (rf24) вместо radio.begin();.... я должен использовать MD_MAX72XX::MD_MAX72XX(moduleType_t mod, uint8_t csPin, uint8_t numDevices):?, @weyhei

Спасибо! Это помогло. Я поменял SI и CLK. { MD_MAX72XX(HARDWARE_TYPE, 11, 8, 53, MAX_DEVICES), "MAX", true }, { MD_MAX72XX(HARDWARE_TYPE, 11, 8, 49, MAX_DEVICES), "MAX", true } Тогда контакты 50,51,52 теперь используются NRF24., @weyhei