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

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

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

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

01#else  // SOFTWARE_SPI
02// define software SPI pins so Mega can use unmodified GPS Shield
03/** SPI chip select pin */
04uint8_t const SD_CHIP_SELECT_PIN = 10;        //поменял на 4--- не помогло
05/** SPI Master Out Slave In pin */
06uint8_t const SPI_MOSI_PIN = 11;
07/** SPI Master In Slave Out pin */
08uint8_t const SPI_MISO_PIN = 12;
09/** SPI Clock pin */
10uint8_t const SPI_SCK_PIN = 13;
11#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 в.

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

01#include <SD.h>
02#include <TMRpcm.h>
03#define D1 7          // Направление вращение двигателя 1
04#define M1 6          // ШИМ вывод для управления двигателем 1
05#define D2 8          // Направление вращение двигателя 2
06#define M2 10         // ШИМ вывод для управления двигателем 2
07char incomingByte;
08bool direction = 0;   // Текущее направление вращения      
09int value;            // Текущее значение ШИМ
10#define SD_ChipSelectPin 4
11TMRpcm tmrpcm;  
12void setup()
13
14  tmrpcm.setVolume(1);
15  tmrpcm.speakerPin = 9;
16  SD.begin(SD_ChipSelectPin);
17  Serial.begin(9600);  
18  pinMode(D1, OUTPUT);
19  pinMode(D2, OUTPUT);
20  pinMode(M1, OUTPUT);
21  pinMode(M2, OUTPUT);
22  Serial.println("ready");
23   if (!SD.begin(SD_ChipSelectPin))     // проверяем наличие sd карты
24      {
25        initialized:
26        Serial.println("SD fail");
27        return;  
28      }
29    else
30      {  
31        Serial.println("SD ok");
32      }
33}
34 
35  
36void motion(char incomingByte)
37{
38  bool directionL, directionR;      // направление вращение для L298N
39  byte valueL, valueR;              // значение ШИМ M1, M2 (0-255)
40 
41  if(incomingByte == 'W') {         // вперёд
42    directionL = 0;
43    directionR = 0;
44    valueL = 60;
45    valueR = 60;
46  }
47   
48  if(incomingByte == 'S') {          // назат
49    directionL = 1;                  //(255-150)
50    directionR = 1;
51    valueL = 195;
52    valueR = 195;
53  }
54   
55  if(incomingByte == 'R') {          // вправо
56    directionL = 0;
57    directionR = 1;
58    valueL = 60;
59    valueR = 195;
60  }
61   
62  if(incomingByte == 'L') {          // влево
63    directionL = 1;
64    directionR = 0;
65    valueL = 195;
66    valueR = 60;
67  }
68   
69  if(incomingByte == 'X') {          // остановка
70  directionL = 0;
71  directionR = 0;
72  valueL = 0;
73  valueR = 0;
74  }
75   
76  analogWrite(M1, valueL);           
77  analogWrite(M2, valueR);           
78  digitalWrite(D1, directionL);      
79  digitalWrite(D2, directionR);
80  Serial.println(direction);
81 
82}
83 
84void loop()
85{
86    if (tmrpcm.isPlaying() == 0)       // проигрываем звук запущенного мотора
87    {
88      tmrpcm.play("e-2mu.wav");
89    }
90  if (Serial.available() > 0)
91    {
92      incomingByte = Serial.read();
93      motion(incomingByte);
94   
95    }
96}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

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

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

01uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
02  errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
03  chipSelectPin_ = chipSelectPin;
04  // 16-bit init start time allows over a minute
05  uint16_t t0 = (uint16_t)millis();
06  uint32_t arg;
07 
08  // set pin modes
09  pinMode(chipSelectPin_, OUTPUT);
10  digitalWrite(chipSelectPin_, HIGH);
11#ifndef USE_SPI_LIB
12  pinMode(SPI_MISO_PIN, INPUT);
13  pinMode(SPI_MOSI_PIN, OUTPUT);
14  pinMode(SPI_SCK_PIN, OUTPUT);
15#endif
16 
17#ifndef SOFTWARE_SPI
18#ifndef USE_SPI_LIB
19  // SS must be in output mode even it is not chip select
20  pinMode(SS_PIN, OUTPUT);
21  digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
22  // Enable SPI, Master, clock rate f_osc/128
23  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
24  // clear double speed
25  SPSR &= ~(1 << SPI2X);
26#else // USE_SPI_LIB
27  SPI.begin();
28  settings = SPISettings(250000, MSBFIRST, SPI_MODE0);
29#endif // USE_SPI_LIB
30#endif // SOFTWARE_SPI
31...

В строках 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" -- имеете ввиду 

1#define SOFTWARE_SPI
2#define USE_SPI_LIB

переделать в 

1#undef SOFTWARE_SPI
2#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() всё верно.