Конфликт библиотек SD и LedControl

Stas0232
Offline
Зарегистрирован: 11.06.2016

Добрый день!

Цель: в проекте необходимо использование microSD и 2-4 разрядного 7-го индикатора. MicroSD необходима для сохранения данных о статистике + воспроизведения голоса с помощью библиотеки TMRpcm. 7-ный индикатор нужен для отображения числовых данных с помощью драйвера Max7221 и библиотеки LedControl. Ниже набросал простой пример кода. 
Проблема: по отдельности все работает(если использовать одно из двух: SD или Max7221). Данные сохраняются и голос воспроизводиться, 7-ный индикатор обновляет значения. Если включать вместе, то индикатор зажигает все сегменты всех разрядов и больше ничего не делает. А SD работает нормально.
Даже нашел в каком моменте ломается. У меня Arduino Leonardo и там пины для SPI другие. Библиотека SD сама выбирает пины в зависимости от контроллера, а в LedControl прописываю в конструктор. У меня это 16 - MOSI и 15 - SCK для LedControl. MISO не используется. Сперва создаю экземпляр LedControl и назначаю нужные пины. И в тот момент когда вызываю метод SD.begin() Max7221 уже отказывается работать. Выводы MOSI и SCK подключены паралельно на Max7221 и на модуль sd карты. Только выводы CS различаются.
Где-то читал, что проблема в таймере, который запускает SD. Отключал прерывания по таймерам на время вывода данных, но все равно не выводит. Даже на время обновления индикатора напрямую пытался поднять CS вывод на sd карте. Не проверял только если LedControl создать после SD.begin() что будет, но во всем проекте нужно раньше.
Можно обойтись и без голоса, думаю, но запись данных с индикатором нужны полюбому. Сомневаюсь, что такая распространенная библиотека должна забирать на себя весь SPI.

Кто сталкивался с такой проблемой или знает конкретное решение, чтобы все работало так, как требуется, прошу помочь.
А да, у меня вот такой модуль microSD.

P.S. Причем интересно, что LedControl не тредует подключения SPI в .ino, а SD требует. Хотя об

#include <LedControl.h>
#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>

/* 
 Инициализация дисплея
 LedControl lc=LedControl(DIN,CLK,LOAD,количество модулей); 
 DIN,CLK,LOAD можно подключать к любым выводам контроллера
 */
LedControl lc=LedControl(16,15,7,1);
TMRpcm tmrpcm;

void setup() {
  pinMode(10, OUTPUT);
  pinMode(6, OUTPUT);
  Serial.println(SD.begin(6));
  
  tmrpcm.speakerPin = 5;
  tmrpcm.setVolume(5); 
  digitalWrite(6, HIGH);
  lc.shutdown(0,false);
  lc.setIntensity(0,10);
  lc.clearDisplay(0);
}

void loop() {   
  lc.clearDisplay(0);
  delay(3000);  
  lc.setDigit(0,0,1,false);
  delay(3000);
  lc.setDigit(0,1,2,false);
  delay(3000);
  tmrpcm.play("1.wav");
}

Когда ставлю комент на //Serial.println(SD.begin(6)); то индикатор работает хорошо) Даже если брать 10 пин, который берется по дефолту не работает.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Проверяйте, чего творится на ногах MOSI и MISO SD-модуля, когда его CS в HIGH - есть подозрение, что на модуле подтяжка к питанию на этих линиях, поэтому у вас все сегменты и горят - единички в линии даже тогда, когда модуль SD отсоединён от линии поднятием CS. У самого такая проблема, сейчас жду http://ru.aliexpress.com/item/Free-shipping-10pcs-74HC125-DIP-logic-ics-SN74HC125N/32670959504.html чтобы разрулить эту ситуацию.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Как используется SS_PIN пин (не знаю, какой он у Леонардо - 10???)?

LedControl на нём живёт?

Stas0232
Offline
Зарегистрирован: 11.06.2016

ЕвгенийП пишет:

Как используется SS_PIN пин (не знаю, какой он у Леонардо - 10???)?

LedControl на нём живёт?

На самом деле расположение SS_PIN не думаю, что будет зависеть от модели ардуинки. На сколько я понимаю это либо HIGH, либо LOW(0 или 5v). То какая разница?
Я специально в приведенном коде убрал и SD и LedControl с 10 пина и ничего другого туда тоже не заведено. 
Третья цифра в объявлении экземпляра класса 
LedControl отвечает за пин:

LedControl lc=LedControl(16,15,7,1);

т.е. используется 7 пин - SS для LedControl.

И 6 пин - SS для SD модуля.

SD.begin(6)

Врядли если при задании в конструкторе другого пина для работы с LedControl(отличного от 10), может как-то и где-то внутри все равно ссылаться на 10 пин(который по дефолту прописан в библиотеках для оборудования, которое общается по SPI).

Stas0232
Offline
Зарегистрирован: 11.06.2016

DIYMan пишет:

Проверяйте, чего творится на ногах MOSI и MISO SD-модуля, когда его CS в HIGH - есть подозрение, что на модуле подтяжка к питанию на этих линиях, поэтому у вас все сегменты и горят - единички в линии даже тогда, когда модуль SD отсоединён от линии поднятием CS. У самого такая проблема, сейчас жду http://ru.aliexpress.com/item/Free-shipping-10pcs-74HC125-DIP-logic-ics-SN74HC125N/32670959504.html чтобы разрулить эту ситуацию.

Попробовал проверить подручными средствами. От модуля не зависит. Отключал модуль SD - та же ерунда. Сама линия передачи данных(MOSI) начиная с инициализации SD командой SD.begin() передает данные только во время этой инициализации и использования других методов для работы с SD. Остальные данные через MOSI (команды которые нужно подать на Max7221 для изменения состояния) походу тупо игнорятся. Отключаю SD.begin() и MOSI активничает при каждой смене значений на индикаторе.​ Что за эгоизм такой! 

Уже на крайняк мне бы подошел аналог SD библиотеки для работы с microSD(голос пришлось бы воспроизводить через какой mp3 модуль), которая не будет игнорить другие устройства на линии SPI. Но хотелось бы, чтобы и эта библиотека, одна из основных библиотек ардуинки, работала с другими устройствами на SPI. 
может я что-то не так делаю? Подскажите решение.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Stas0232 пишет:

Врядли если при задании в конструкторе другого пина для работы с LedControl(отличного от 10), может как-то и где-то внутри все равно ссылаться на 10 пин(который по дефолту прописан в библиотеках для оборудования, которое общается по SPI).

Ещё как может. Библиотека SD при некоторых условиях именно так и делает. Стал бы я спрашивать :)

Stas0232
Offline
Зарегистрирован: 11.06.2016

ЕвгенийП пишет:

Ещё как может. Библиотека SD при некоторых условиях именно так и делает. Стал бы я спрашивать :)

Только все равно непонятно причем тут конструктор LedControl(он никакого отношения к SD не имеет).
А насчет SD. Ставил SD.begin(10), чтобы по дефолту брало для SD 10 пин. Все равно тот же результат.

В SD что-то блокирует линии(по крайней мере MOSI) и другие команды после этого по SPI не проходят на другие устройства. А что блокирует и как этого избежать - пока еще не понял. Это и есть проблема.

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Stas0232 пишет:
Когда ставлю комент на //Serial.println(SD.begin(6)); то индикатор работает хорошо) Даже если брать 10 пин, который берется по дефолту не работает.

Я, конечно, дико извиняюсь, но объясните мне пожалуйста смысл этого действия:

Serial.println(SD.begin(6));

Что ожидается увидеть в мониторе порта при этом?

Еще бы я, Бог с ним, убрал комментарные косые с этого оператора и до него и после поставил бы такую группу:

Serial.println(SS);
Serial.println(MOSI);
Serial.println(MISO);
Serial.println(SCK);

...и посмотрел бы бы что изменилось.

И еще: для SD лучше SS(CS) оставить на 10-м пине и "обозвать" его как:

pinMode(SS, OUTPUT);

 

Stas0232
Offline
Зарегистрирован: 11.06.2016

Buzzer2010 пишет:

Я, конечно, дико извиняюсь, но объясните мне пожалуйста смысл этого действия:

Serial.println(SD.begin(6));

Что ожидается увидеть в мониторе порта при этом?

Если увидело microSD, то вернет 1. Источник.

Buzzer2010 пишет:

Еще бы я, Бог с ним, убрал комментарные косые с этого оператора и до него и после поставил бы такую группу:

Serial.println(SS);
Serial.println(MOSI);
Serial.println(MISO);
Serial.println(SCK);

...и посмотрел бы бы что изменилось.

ничего! ниже привел пример вывода с компорта.

Вот скетч чтобы проверить что твориться на линиях(по идее реализация верная):

#include <LedControl.h>
#include <SD.h>
#include <SPI.h>
//#include <TMRpcm.h>

/* 
 Инициализация дисплея
 LedControl lc=LedControl(DIN,CLK,LOAD,количество модулей); 
 DIN,CLK,LOAD можно подключать к любым выводам контроллера
 */
LedControl lc=LedControl(16,15,7,1);
//TMRpcm tmrpcm;
File file;
int i;

void setup() {
  Serial.begin(9600);
  pinMode(SS, OUTPUT);
  pinMode(6, OUTPUT);
  attachInterrupt(0, func_test, RISING);
  delay(3000);
  Serial.println("-*-");
  Serial.println(SS);
  Serial.println(MOSI);
  Serial.println(MISO);
  Serial.println(SCK);
  Serial.println();
  Serial.println(SD.begin(6));
  Serial.println();
  Serial.println();
  Serial.println(SS);
  Serial.println(MOSI);
  Serial.println(MISO);
  Serial.println(SCK);
  Serial.println("-*-");

  //tmrpcm.speakerPin = 5;
  //tmrpcm.setVolume(5); 
  digitalWrite(6, HIGH);  
  Serial.println("-0-");
  lc.shutdown(0,false);
  lc.setIntensity(0,10);
  lc.clearDisplay(0);
  
}

void loop() {  
  delay(3000);
  Serial.println("-1-"); 
  lc.clearDisplay(0);
  delay(3000);
  Serial.println("-2-");
  lc.setDigit(0,0,1,false);
  delay(3000);
  Serial.println("-3-");
  lc.setDigit(0,1,2,false);
  delay(3000);
  Serial.println("-4-");
  //tmrpcm.play("1.wav");
  delay(3000);
  Serial.println("-5-");
  print_temperature();
}

void func_test(void)
{
  if (i < 100)
  {
    Serial.print(digitalRead(3));
    //Serial.print("/");
    i++;
  }
  else
  {
    Serial.println(digitalRead(3));
    i = 0;
  }
}

void print_temperature(){
    file = SD.open("222.txt", FILE_WRITE);
    file.print(digitalRead(3));
    file.println(";");
    file.close();
}

Просто нужно зацепить MOSI или другую ногу на пин внешних прерываний по нулевому таймеру(3 пин - леонардо, 2 пин - Uno). Я проверял MOSI. Тут видно даже без подключения какого либо оборудования, что происходит на линии(точнее видно что состояние на линии MOSI меняется). Могли бы вы проверить этот скетч, будет ли приходить инфа между пунктами 1-3 и в 5 пункте. 
У меня при раскоменчивании SD.begin(6) ничего не происходит в 0-3 пунктах, но 5 пункт активно меняет 0 на 1. А при коментах на этой строчке все наоборот(1-3 активно, а 5 пункт спит). Вот пример:

При //Serial.println(SD.begin(6));
=============================================

-*-
17
16
14
15
 
 
 
17
16
14
15
-*-
-0-
111111111111111-1-
111111111-2-
11-3-
1111-4-
-5-
====================================================
 
При Serial.println(SD.begin(6));
====================================================
-*-
17
16
14
15
 
101111111011111111111110101111111111010111111111111111111111111111111111111111111111111
 
 
17
16
14
15
-*-
-0-
-1-
-2-
-3-
-4-
-5-
11111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111<дальше еще пару строчек единичек>
==============================================

Складывается подозрение, что это из-за леонарды. SS показывает 17 порт, даже после всех действий, а этот 17 порт вообще на леонардо не выведен, только можно подпояться. Хотя карта и светодиоды по отдельности при инициализации работают. Проверьте кто на UNO.

 

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

А может сделать вот так:

int pin_6 = 0;
  pin_6 = int(SD.begin(6));
   Serial.println(pin_6);

Возможно прям сразу выводить не получается? И не понятно, кстати: если "SS" висит на 17 пине, какой смысл стартовать SD с 6-го?

И второе: IDE точно настроено на Leonardo? Потому что поковырявшись в библиотеках я заметил что для каждого типа Arduino SS, MOSI, MISO и SCK назначаются совершенно на определенные пины! В сектчах для UNO, SS висит на 10-м пине, но мне его оттуда сдвигать смысла нет - у меня SD-ридер на шилде и тупо вставлен в 10-й пин. А вот для DUE у меня ридер самодельный, но слезть с 10 пина можно только начав ковырять "Arduino.h", а туда я лезть побоялся да и незачем: свобдных пинов как собак нерезаных...

Это я к чему веду: если IDE компилирует скетчи для Leonardo, то врядли оно будет тулить SS на несуществующий на плате пин...

Но это мнение дилетанта, прошу учесть! ))

 

Stas0232
Offline
Зарегистрирован: 11.06.2016

Buzzer2010 пишет:

А может сделать вот так:

int pin_6 = 0;
  pin_6 = int(SD.begin(6));
   Serial.println(pin_6);

Возможно прям сразу выводить не получается? И не понятно, кстати: если "SS" висит на 17 пине, какой смысл стартовать SD с 6-го?

Я пробовал и просто вызывать SD.begin(6). Не в этом проблема... На самом деле странно, что пишет 17, но после инициализации работает на 7. Поставишь SD.begin(8) или SD.begin(10) - будет работать соответственно на 8 и 10. И причем только на том, который задан в SD.begin().

Buzzer2010 пишет:

И второе: IDE точно настроено на Leonardo? Потому что поковырявшись в библиотеках я заметил что для каждого типа Arduino SSMOSIMISO и SCK назначаются совершенно на определенные пины! В сектчах для UNOSS висит на 10-м пине, но мне его оттуда сдвигать смысла нет - у меня SD-ридер на шилде и тупо вставлен в 10-й пин.

...

Это я к чему веду: если IDE компилирует скетчи для Leonardo, то врядли оно будет тулить SS на несуществующий на плате пин...

Точно на Леонардо, поэтому и такие пины. 17 пин этот как раз пин, который библиотека определяет для Леонардо, просто он напрямую не выведен на плату. Почему - не знаю. Вот ссылка.

Отсюда и возникает подозрение, что именно на Леонардо она криво работает(хотя и сомнительные). Мне не важно какой пин, я поставлю любой(какой подойдет).

Вообще говоря, я разрабатываю проект под atmega328p-pu, который висит на UNO, так что мне даже более подходило бы UNO, а не Леонардо, но пока еще нету. Поэтому и прошу на UNO запустить и проверить этот(второй) скетч, который я закинул. Поставьте в SD.begin() любой пин, хоть даже SS. Мне важно будут ли приходить единички меджу пунктами 0-3, когда SD.begin() не закомментирован у вас в скетче на UNO?! Даже не нужно ничего подключать к UNO(только вывод MOSI зацепить на вроде как 2 пин в уне), MOSI и так должно высылать данные.

P.S. я привел два примера работы: раскомментирована SD.begin() - единички не приходят между 0-3(теоретически MOSI не отсылает ничего); закомментирована SD.begin() - единички приходят между 0-3(сразу видно, что при каждой команде, MOSI что-то высылает).

Stas0232
Offline
Зарегистрирован: 11.06.2016

Появились новые подозрения, что это как раз не библиотека SD работает неверно, но LedControl. Складывается ощущение, что она работает по какому-то своему протоколу SPI и из-за этого конфликтует с SD, которая работает с библиотекой SPI. Но еще не проверял.
Вобщем вопрос остается актуальным: Помогите заставить работать microSD с библиотекой TMRpcm и 7-ный индикатор с драйвером MAX7221 ОДНОВРЕМЕННО(в одном проекте). Может есть аналоги библиотек или еще какие варианты?

Stas0232
Offline
Зарегистрирован: 11.06.2016

Решение найдено. Правда на другом сайте.

Смысл в следующем. Библиотека SD использует "аппаратный" SPI, а LedControl - программный(создатель этой библиотеки не привязывался к стандарному использованию SPI в ардуино). Поэтому когда я вешал и sd-карту и 7-ный индикатор на одни входы SPI, то одно перебивало работу другого и невозможно было использовать их совместно.

Решение проблемы. Какой-то(по определению полезный) человек переписал библиотеку LedControl на "аппаратный"(стандартно используемый) SPI. Вот ссылка на эту библиотеку. Там немного меняется инициализация, а все остальное такое же:

LedControl lc=LedControl(7,1)  //LedControl(int csPin, int numDevices)

Библиотеку проверил. У меня все заработало так, как и нужно. Пользуйтесь на радость. :)

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

спасибо, очень полезно, а то тоже столкнулся и не пашет вместе никак ) а тут вон в чем дело всё было )

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ELITE пишет:

 тоже столкнулся и не пашет 

Как, и это тоже? :))))))))))))

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

это камень в огород ардуины - это надо было додумаься в список официальных библиотек положить библиотеку и не предупредить, что она не работает на аппаратном СПИ...

//а автору библиотеки на заметку - МАХ7219/7221 работают на частоте 8МГц, а не 10, как это включено в библиотеку...

//у меня вообще выше 3.8МГц не включилось.... хотя вроде МАХ7221 оригинальные.... 
// при этом снизить пришлось до 1МГц - тк выше начинались сбои при передачи (помехочувствительность с ростом частоты также возрастала) на 1МГц заработало стабильно и более не реагировало на прикосновения к проводам и платам

-----

//и да, в огород производителю чипов - свистят они не по детски, при этом не только на 8МГц, но и ввобще в широком спектре - радио в 2х метров у меня глушит при включении... 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А главное Ардуину "!!!НЕ КИПЯТИТЬ!!!"  https://www.anekdot.ru/id/-1102423010/

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ELITE пишет:

это камень в огород ардуины

Так и я ж про тоже, камень всегда найдётся куда присторить.

ELITE пишет:

а автору библиотеки на заметку - МАХ7219/7221 работают на частоте 8МГц, а не 10, 

Производитель в даташите пишет 10, но, я понимаю, он дурак и это камень в его огород.

ELITE пишет:

у меня вообще выше 3.8МГц не включилось.... хотя вроде МАХ7221 оригинальные....

И почему меня это не удивляет? У Вас вообще хоть что-нибудь включилось? У Вас и циклы не работают, и 1+2 не складывается, и strcpy с atoi криво реализованы (это всё камни в соответствующие огороды, разумеется). 

У меня, кстати, на 10МГц почему-то работает. Не подскажете, что я делаю не так?

ELITE пишет:

и да, в огород производителю чипов - свистят они не по детски, при этом не только на 8МГц, но и ввобще

Так она ж у Вас только на 3.8МГц запустилась, откуда 8-то?

:)))))))))))))))))))))))))

 

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

qwone пишет:

А главное Ардуину "!!!НЕ КИПЯТИТЬ!!!"  https://www.anekdot.ru/id/-1102423010/

а почему? :( я же для машины делаю...

а то я 2 года назад случайно замочил видеорегистратор у зеркала на лобовом....

а ардуина то будет ниже стоять - там же электроники поменьше, да и провода потолще - она сломается в воде тоже? :(

ELITE
ELITE аватар
Offline
Зарегистрирован: 11.01.2018

ЕвгенийП пишет:

Производитель в даташите пишет 10, но, я понимаю, он дурак и это камень в его огород.

Так она ж у Вас только на 3.8МГц запустилась, откуда 8-то?

хм, по китайскому даташиту на мах7219/7221 указано 8мгц

а по чисто на 7221 - 10мгц...

ну да не сильно важно - зачем на максимальной частоте гнать то.... 

я хз, но думаю у меня выше 3.8 не завелось изза качества проводов и платы - они все самодельные и быстрее всего много наводок и помех вот и не идет как надо

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Блин, так у Вас не только С нечестный, Вы и даташиты умудряетесь где-то нечестные раздобыть! Как Вы всё это делаете?