Проблема с 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();
@weyhei, 👍0
1 ответ
Лучший ответ:
Я заглянул в исходный код библиотеки 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 }
};
- SPI с преобразователем уровня на другом конце соединения
- Как использовать SPI на Arduino?
- Путаница между SPI и I2C для SSD1306 OLED
- Неправильная документация для выводов Mega2560 SPI?
- Есть ли подробные примеры Si4463?
- Взаимодействие с датчиком SSI?
- NRF24L01+ PA не работает с Arduino Mega (работает с Nano)
- RaspberryPi Pico SPI и nrf24l01
Вы предлагаете инициализировать трансивер (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