Проблема с spi, можно ли использовать pin 10 arduino для своих нужд?

EpeTuk
Offline
Зарегистрирован: 04.09.2016

Всем привет, делаю танк на блютуз управлении, со стрельбой через ик передатчик/приёмник, воспроизвожу звуки двигателя, управляю моторами.

Столкнулся с такой проблемой: Подключаю флешку, воспроизвожу с неё звуки, для CS использую 4 пин ардуино про мини 328 5в. При этом управляю моторами: 2 мотора, нужно два pwm вывода. Планировал использовать 10-ый и 6-ой пины, остальные заняты под стрельбу подключение флешки и воспроизведение звуков. Но хотя и использую 4 пин для чип селекта флешки, на 10 пине у меня всёравно логическая 1 т.е ~5 вольт, естественно об управлении мотором через этот пин речи не идёт. Полазил по либам, нашёл в Sd2Card.h строки: 

#else  // SOFTWARE_SPI
// define software SPI pins so Mega can use unmodified GPS Shield
/** SPI chip select pin */
uint8_t const SD_CHIP_SELECT_PIN = 10;        //поменял на 4--- не помогло
/** SPI Master Out Slave In pin */
uint8_t const SPI_MOSI_PIN = 11;
/** SPI Master In Slave Out pin */
uint8_t const SPI_MISO_PIN = 12;
/** SPI Clock pin */
uint8_t const SPI_SCK_PIN = 13;
#endif  // SOFTWARE_SPI

Полазил по форумам, но так и не понял можно ли отключить использование 10 пина или он всегда поумолчанию задействован при использовании spi?   

Очень прошу помочь, зарание спасибо

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

Вы имеете в виду аппаратный SPI в режиме Master, очевидно. Так? Пин 10 - это SS (если я не ошибаюсь). Ответ на Ваш вопрос содержится в п. 19.3.2 даташита. А именно.

1) Если Вы определите пин 10 как OUTPUT - то никаких проблем, делайте с ним что хотите, он не мешает SPI.

2) Если же Вы определите его как INPUT, то там должен быть HIGH. Как только там появится LOW, SPI слетит в режим Slave. В принципе ничего страшного, если после этого снова ручками выставить нужный режим, прежде чем начать пользоваться SPI.

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

А то, что Вы меняли - так там же параметры для программного SPI - чего толку их менять, если Вы используете аппаратный?

Для программного (если его использовать) проблемы нет вообще - ему пофигу какие там пины.

Вполне возможно, что его использует Ваша библиотека и Вы правильно сделали, что в неё полезли. Но Вы найдите где она его использует с аппаратным, а не программным SPI и там меняйте.

EpeTuk
Offline
Зарегистрирован: 04.09.2016

ну получается что аппаратный 11 12 13 пины

Если Вы определите пин 10 как OUTPUT - то никаких проблем, делайте с ним что хотите, он не мешает SPI. --- не помогает( всёравно на выходе 5 в.

пример кода тестового 

#include <SD.h>
#include <TMRpcm.h>
#define D1 7          // Направление вращение двигателя 1
#define M1 6          // ШИМ вывод для управления двигателем 1
#define D2 8          // Направление вращение двигателя 2
#define M2 10         // ШИМ вывод для управления двигателем 2
char incomingByte; 
bool direction = 0;   // Текущее направление вращения       
int value;            // Текущее значение ШИМ
#define SD_ChipSelectPin 4
TMRpcm tmrpcm;   
void setup() 
{  
  tmrpcm.setVolume(1);
  tmrpcm.speakerPin = 9;
  SD.begin(SD_ChipSelectPin);
  Serial.begin(9600);   
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(M1, OUTPUT);
  pinMode(M2, OUTPUT); 
  Serial.println("ready");
   if (!SD.begin(SD_ChipSelectPin))     // проверяем наличие sd карты
      {
        initialized:
        Serial.println("SD fail");
        return;   
      }
    else
      {   
        Serial.println("SD ok");
      } 
}

 
void motion(char incomingByte) 
{
  bool directionL, directionR;      // направление вращение для L298N
  byte valueL, valueR;              // значение ШИМ M1, M2 (0-255)

  if(incomingByte == 'W') {         // вперёд
    directionL = 0;
    directionR = 0;
    valueL = 60;
    valueR = 60;
  }
  
  if(incomingByte == 'S') {          // назат
    directionL = 1;                  //(255-150)
    directionR = 1;
    valueL = 195;
    valueR = 195;
  }
  
  if(incomingByte == 'R') {          // вправо
    directionL = 0;
    directionR = 1;
    valueL = 60;
    valueR = 195;
  }
  
  if(incomingByte == 'L') {          // влево
    directionL = 1;
    directionR = 0;
    valueL = 195;
    valueR = 60;
  }
  
  if(incomingByte == 'X') {          // остановка
  directionL = 0;
  directionR = 0;
  valueL = 0;
  valueR = 0;
  }
  
  analogWrite(M1, valueL);            
  analogWrite(M2, valueR);            
  digitalWrite(D1, directionL);       
  digitalWrite(D2, directionR); 
  Serial.println(direction);

}

void loop() 
{ 
    if (tmrpcm.isPlaying() == 0)       // проигрываем звук запущенного мотора
    {
      tmrpcm.play("e-2mu.wav"); 
    }
  if (Serial.available() > 0)
    {
      incomingByte = Serial.read();
      motion(incomingByte);
  
    }
}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я там дописал текст: "Вполне возможно, что его использует Ваша библиотека и Вы правильно сделали, что в неё полезли. Но Вы найдите где она его использует с аппаратным, а не программным SPI и там меняйте".

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

Вот смотрите, в библиотеке SD, в файле Sd2Card.cpp есть функция инициализации

uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
  errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
  chipSelectPin_ = chipSelectPin;
  // 16-bit init start time allows over a minute
  uint16_t t0 = (uint16_t)millis();
  uint32_t arg;

  // set pin modes
  pinMode(chipSelectPin_, OUTPUT);
  digitalWrite(chipSelectPin_, HIGH);
#ifndef USE_SPI_LIB
  pinMode(SPI_MISO_PIN, INPUT);
  pinMode(SPI_MOSI_PIN, OUTPUT);
  pinMode(SPI_SCK_PIN, OUTPUT);
#endif

#ifndef SOFTWARE_SPI
#ifndef USE_SPI_LIB
  // SS must be in output mode even it is not chip select
  pinMode(SS_PIN, OUTPUT);
  digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
  // Enable SPI, Master, clock rate f_osc/128
  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
  // clear double speed
  SPSR &= ~(1 << SPI2X);
#else // USE_SPI_LIB
  SPI.begin();
  settings = SPISettings(250000, MSBFIRST, SPI_MODE0);
#endif // USE_SPI_LIB
#endif // SOFTWARE_SPI
...

В строках 20 и 21 используется явный SS_PIN. Вот там он и ставится в HIGH

Только я не понимаю чем Вам это мешает. Вас ведь устраивает, что он OUTPUT? Ну, а если устраивает, то сделайте его LOW или что Вам там надо. Библиотека его больше нигде всё равно не использует.

EpeTuk
Offline
Зарегистрирован: 04.09.2016

Как то неособо что то поменялось(. Заметил такую особенность: вроде работает, потом через пару секунд что то происходит на на выход начинает подаваться 1 или 0 (5/0в)в зависимости от того что ставили в библиотеке low or high

 

 

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

Убедитесь, что у Вас обе константы

SOFTWARE_SPI
USE_SPI_LIB
 
НЕ определены. Если надо, разопределите их #undef
 
В этом случае библиотека SD вообще не прикасается к этому пину, кроме тех двух строк. на них просто плюёте. Ну поставила она в OUTPUT и HIGH - а Вы ставьте как Вам надо.
 
Только обязательно сделайте. чтобы эти константы не были определены. Особенно вторая. Я не знаю, что делает с этим пином библиотека SPI, а лезть неохота, но если константа не будет определена, то библиотека SPI не быдет использоваться, и слава Богу.
EpeTuk
Offline
Зарегистрирован: 04.09.2016

простите мою глупость, недавно занялся ардуино,  SOFTWARE_SPI, USE_SPI_LIB где не должны быть определены? в Sd2Card.cpp? "НЕ определены. Если надо, разопределите их #undef" -- имеете ввиду 

#define SOFTWARE_SPI
#define USE_SPI_LIB

переделать в 

#undef SOFTWARE_SPI
#undef USE_SPI_LIB

в самой либе?

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

Там как-то не по уму сделано. Та же USE_SPI_LIB определяется дважды один раз в Sd2Card.h, и второй раз в самом начале Sd2Card.cpp.

В общем, попробуйте найти все их определения и просто закомментировать строки типа

#define SOFTWARE_SPI
#define USE_SPI_LIB

Добавте // в начало

//#define SOFTWARE_SPI
//#define USE_SPI_LIB

ТОлько все найдите, а то авторы библиотеки такие затейники.

EpeTuk
Offline
Зарегистрирован: 04.09.2016

ну как коментить я знаю))) спасибо сейчас попробую

EpeTuk
Offline
Зарегистрирован: 04.09.2016

прошёлся по всем файлам в либе с поиском. попробовал так же закоментить все ifdef, как я понял там 2 варианта если #ifdef SOFTWARE_SPI #ifdef USE_SPI_LIB описывает что будет если определенны. Но с таки варианто либа не компилится.

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

И чего? Неужели, не заработало?

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

EpeTuk пишет:

 попробовал так же закоментить все ifdef, 

Ни в коем случае!

EpeTuk
Offline
Зарегистрирован: 04.09.2016

ничего не меняется(

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

Ну, это мистика.

Там же никто эту несчастную ногу не трогает.

Т.е. Вы ставите, например, LOW, а через какое-то время она сама по себе становится HIGH?

Так не бывает.

Поищите поиском по всем файлам библиотеки SS_PIN. Может я где пропусти и он таки меняется где-то ещё, кроме тех двух строк.

Кстати, а вторая Ваша библиотека не может его обижать? 

EpeTuk
Offline
Зарегистрирован: 04.09.2016

блин занят) так бы мог видео доказательство снять)

 

EpeTuk
Offline
Зарегистрирован: 04.09.2016

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

вторая Ваша библиотека не может его обижать? 

Во второй либе может использоваться пин 10 для второго динамика как я понял, но эта функция отключена, методом тыка проверял что глюки начинаются сразу после SD.begin(SD_ChipSelectPin). до этого момента всё работает

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

Мне не нужно никаких доказательств, с чего мне Вам не верить-то?

Поясните толком - какие глюки.

То. что после SD.begin(SD_ChipSelectPin) пин станет HIGH - это нормально. Сделайте его Low если Вам надо и пользуйте дальше.

Я так понял Вас, что Вы делаете его LOW, а он в какой-то момент сам по себе HIGH становится. В какой момент? Можете выяснить?

EpeTuk
Offline
Зарегистрирован: 04.09.2016

Я тут наткнулся на тему http://forum.arduino.cc/index.php?topic=129538.0 Насколько я понял у человека такая же проблема была 

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

Ну, Вы на мой вопрос-то ответьте.

EpeTuk
Offline
Зарегистрирован: 04.09.2016

Так ну истина гдето рядом): навсякий закинул все чистые либы, ещё раз прошёлся по SD: всё начало работаь замечательно, пропали неадыкватные вращения мотора при включении, НО до того момента пока не начинаю музыку воспроизводить: 10 пин становится неадыкватным. + 9 пине динамик и при использовании шима на 10 мини усилитель усиливает писк шима))) чувствую придётся плату переделывать освобождать 5 и юзать 5-7 6-8 для управления движками а ик приёмник вешать 4, ss -10 

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

А не проще частоту ШИМа увеличить килогерц до 30-60 и нехай себе усиливает (заодно комаров ультразвуком распугает) :))))

EpeTuk
Offline
Зарегистрирован: 04.09.2016
EpeTuk
Offline
Зарегистрирован: 04.09.2016

ок, спс за совет, спрашивать как, не буду- гугл не забанил) хотя в digitalWrite(D1, 155);  155 это будет частота или скважность?

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

Это скважность.

Частоту можно настроить до 62КГц.

Как можно найти на форумах, но быстрее просто посмотреть в даташите.

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

EpeTuk пишет:

digitalWrite(D1, 155);  155 это будет частота или скважность?

Это будет неправильно. digitalWrite() выдаёт только HIGH или LOW. А ШИМ сигнал с регулировкой скважности выдаёт analogWrite().

 

EpeTuk
Offline
Зарегистрирован: 04.09.2016

пардон analogWrite() всё верно.