Конфликты SPI и Serial

mgm_arduino
Offline
Зарегистрирован: 11.03.2016

Здравствуйте уважаемые форумчане, программирую на ардуино НАНО проект с бегущей строкой.

Идея: Плата принимает данные через пины RX TX, расшифровывает, и показывает бегущую строку.

бегущая строка сформирована из трех модулей LED (32x16), подключенных через библиотеку DMD.

Данные принимаю c другого устройства через интерфейс RS-485, преобразую драйвером RS485-RS232, подключаю к RX TX пинам ардуино.

Проблема: Создал проект который слушает Serial и выводит опять в Serial

  if(Serial.available()){
    Serial.write(Serial.read());
  }

данные получаю, никаких проблем нет. Проблемы возникают когда я пытаюсь прикрутить бегущую строку. Строка работает, но нет взаимодействия с серийным портом (данные не идут). Пытался сделать вот так

#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);

void setup(void) {
  Serial.begin(115200);
  mySerial.begin(115200);
}

void loop(void) {
  if(mySerial.available()){
    Serial.write(mySerial.read());
  }
}

тоже самое. Есть подозрения что это какой то конфликт SPI и Serial.  Может кто нибудь сталкивался?

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

Простите, не понял, а SPI тут каким боком?

mgm_arduino
Offline
Зарегистрирован: 11.03.2016

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

Простите, не понял, а SPI тут каким боком?

 

когда к этой програмке которую привел пример подключаю библиотеку DMD (бег. строка - SPI), то уже не могу получить данные с RX TX пинов на ардуино

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

Ну так и приводите программу, которая неправильно работает. Зачем Вы эту-то привели?

mgm_arduino
Offline
Зарегистрирован: 11.03.2016
#include <EEPROM.h>
#include <SPI.h>       
#include <DMD.h>       
#include <TimerOne.h>   

//#include "Arial_black_16.h"
//#include "ArialBlack_16_ISO8859_5.h"
//#include "SystemFont5x7.h"

#define SerialTxControl 12   //RS485 управляющий контакт на arduino pin 10
#define RS485Transmit    HIGH
#define RS485Receive     LOW  

#include "bnArialBlack16Cyr12ft.h"
#include "bnArialBlack16Cyr14ft.h"




// ****** UTF8-Decoder: convert UTF8-string to extended ASCII *******
static byte c1;  


byte utf8ascii(byte ascii) {
    if ( ascii<128 )    
    {   c1=0; 
        return( ascii ); 
    }

    // get previous input
    byte last = c1;   
    c1=ascii;         

    switch (last)     
    {   
        case 0xD0: return (ascii+0x20);
        case 0xD1: return (ascii+0x60);
    }

    return  0;                                    
}

// convert String object from UTF8 String to Extended ASCII
String utf8ascii(String s)
{       
        c1 = 0;
        String r="";
        char c;
        for (int i=0; i<s.length(); i++)
        {
                c = utf8ascii(s.charAt(i));
                if (c!=0) r+=c;
        }
        return r;
}













//Fire up the DMD library as dmd
DMD dmd(3,1);

bool dmd_enabled = true;
bool send_speed = false;


byte pixel = GRAPHICS_NORMAL;



void ScanDMD(){dmd.scanDisplayBySPI();}

String inData;

String textToScroll; 


void setup(void){

  Serial.begin(115200);
   pinMode(SerialTxControl, OUTPUT);  
   digitalWrite(SerialTxControl, RS485Transmit); 
   //Serial.println("TEST");  
  delay(100); 
  



  //EEPROM.get 
  
  //check on eor
  



  //pinMode(SerialTxControl, OUTPUT);  
  //digitalWrite(SerialTxControl, RS485Transmit); 
  
  
  Serial.println("bnav.ru -- initializing ....");
  //Serial.println(digitalRead(11));
  //Serial.println(EEPROM.length());
     
  
  randomSeed(analogRead(0)); // random 

  //pinMode(2, INPUT);
  digitalWrite(2, HIGH); // for correction
  //Serial.println(getNum());




  Serial.print("attach interrupt ScanDMD ... ");
  Timer1.initialize(4000);        
  Timer1.attachInterrupt(ScanDMD);  

  Serial.println("ok");

  dmd.selectFont(bnArialBlack16Cyr12ft);
  dmd.drawString(2,1,"ok-",4,GRAPHICS_NORMAL);
  delay(1000);

  Serial.print("checking screen ... ");
  dmd.drawFilledBox(0,0,31,15,pixel);
  dmd.drawFilledBox(0,0,31,15,!pixel);
  dmd.drawBox(0,0,31,15,pixel);
  delay(1400);


  Serial.println("ok");
  Serial.print("checking speed ... ");
  dmd.clearScreen(true);  

  Serial.println("ok");

  

  Serial.print("attach interrupt onPulse ... ");
//  attachInterrupt(digitalPinToInterrupt(2), onPulse, RISING);

    Serial.println("ok");

    Serial.println("ready");
    Serial.println(textToScroll);

    drawText("Приветствуем Вас на маршруте 102");
      delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);
}





void drawText(String dispString) {
  String realString = utf8ascii(dispString);
  dmd.clearScreen( true );
  //dmd.selectFont(ArialBlack_16_ISO8859_5);

  dmd.selectFont(bnArialBlack16Cyr12ft);
  dmd.selectFont(bnArialBlack16Cyr14ft);
  char newString[256];
  int sLength = realString.length();

  Serial.println(dispString);
  realString.toCharArray( newString, sLength+1 );
  dmd.drawMarquee( newString , sLength , ( 32*3 )-1 ,-1);
  long start=millis();
  long timer=start;
  long timer2=start;
  boolean ret=false;
  while(!ret) {
    if ((timer+20) < millis()) {
      ret=dmd.stepMarquee( -1, 0 );
      timer=millis();
    }
  }
}

void loop() {
  
  digitalWrite(SerialTxControl, RS485Receive);  // читаем данные с порта
  if(Serial.available()){
    Serial.write(Serial.read());

  }
 

  
 



}

 

releyshic
Offline
Зарегистрирован: 20.11.2015

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

Ну так и приводите программу, которая неправильно работает. Зачем Вы эту-то привели?

просто по правилам форума положено Код приводить, а какой это уже не сказано )))))))))

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

В наших узких кругах считается что 115200 многовато будет для софтварного  сериала.

releyshic
Offline
Зарегистрирован: 20.11.2015

trembo пишет:

В наших узких кругах считается что 115200 многовато будет для софтварного  сериала.

должно работать хоть коряво но работать

между прочим даже Marlin (хрен его знает есть ли что тяжелее вообще) на такой скорости работает а эта шалупонь и подавно должна

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

releyshic пишет:

trembo пишет:

В наших узких кругах считается что 115200 многовато будет для софтварного  сериала.

должно работать хоть коряво но работать

Обьясните мне что такое "коряво работающий сериал порт" и что вы хотите с него считать?

Это как раньше телевизор на даче: еле видная картинка среди шумов?

http://arduino.stackexchange.com/questions/21465/softserial-max-speed-lo...

https://github.com/arduino/Arduino/issues/2019

releyshic
Offline
Зарегистрирован: 20.11.2015

trembo пишет:

Это как раньше телевизор на даче: еле видная картинка среди шумов?

именно так. вот тогда и можно было бы тут о скоростях рассуждать. а если совсем не работает значит не работает

тем более не коды запуска ракет передавать ))

mgm_arduino
Offline
Зарегистрирован: 11.03.2016

мне кажется дело не в скорости 115200. ведь данные приходят с другого устройства (именно данные, а не набор байт!) 

 

к примеру 



#include <DMD.h>       
 



// DMD dmd_screen(3,1);

void setup(void){

  Serial.begin(115200);

}

/*--------------------------------------------------------*/

void loop() {
  
   // читаем данные с порта
  if(Serial.available()){
    Serial.write(Serial.read()); //при закоментированной переменной dmd_screen данные получаю

  }
}

вот если запустить программу, она будет выводить все что придет на пин RX. если раскоментировать строку

// DMD dmd_screen(3,1);

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

Библиотеку DMD использовал здесь https://github.com/freetronics/DMD

 

releyshic
Offline
Зарегистрирован: 20.11.2015

очень странно я посмотрел бибилиотеку DMD и не видел в контрукторе там ничего такого, что могло бы мешать

mgm_arduino
Offline
Зарегистрирован: 11.03.2016

путем комментирования строк нашел проблемные места. в файле SPI.cpp строка 26

void SPIClass::begin()
{
  [. . .]

    // Warning: if the SS pin ever becomes a LOW INPUT then SPI
    // automatically switches to Slave, so the data direction of
    // the SS pin MUST be kept as OUTPUT.
    SPCR |= _BV(MSTR); // вот именно после этих строк перестает работать серийный порт через RX
    SPCR |= _BV(SPE);

  [. . .]
}

как эти регистры могут мешать? понять не могу

mgm_arduino
Offline
Зарегистрирован: 11.03.2016

Народ, никто разве не сталкивался с таким

Logik
Offline
Зарегистрирован: 05.08.2014

Похоже на конфликт по скорости. Оба интерфейса быстрые, на прерываниях и производительности не хватает. Для диагностики понизьте скорости обоих.

releyshic
Offline
Зарегистрирован: 20.11.2015

Logik пишет:

Похоже на конфликт по скорости. Оба интерфейса быстрые, на прерываниях и производительности не хватает. Для диагностики понизьте скорости обоих.

"Warning: if the SS pin ever becomes a LOW INPUT then SPI

06     // automatically switches to Slave, so the data direction of
07     // the SS pin MUST be kept as OUTPUT.

вот это вот переведи на нормальный русский мне кажется тут и разгадка )

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

А чего тут переводить. Если SPI Работает в мастер-режиме, то пин SS обязан быть либо в OUTPUT, либо если уж в INPUT, то хотя бы HIGH. А если он станет INPUT/LOW SPI сам переключится в Slave режим.

releyshic
Offline
Зарегистрирован: 20.11.2015

у нашего гения нет решения  вопроса  ))

Кстати возможнео дело в  Serial.

Он как раз запросто может забивать всё что угодно, ведь основное назначение для связи с компом + монитор порта его пользует ип глюки могут быть

 

Мне кажется надо попробовать у когонибудь ещё скетч запустить

mgm_arduino
Offline
Зарегистрирован: 11.03.2016

вот пример скетча который не работает. в плате ардуино надо соединить RX пин и D13.

//надо соединить RX пин и D13

void setup(void){
   
   //SPCR |= _BV(SPE); //раскоментируем и перестанет принимать
   pinMode(13, OUTPUT);
   Serial.begin(115200);

}


void loop() {
  digitalWrite(13, HIGH);
  digitalWrite(13, LOW);
  digitalWrite(13, HIGH);
  delay(10);
  if(Serial.available()){
    Serial.write(Serial.read());
  }
  delay(100);
}

при закоментированной строке данные идут. когда строку оставляем - пин RX наотрез перестает видеть что либо

в описании к SPI ничего не написано про конфликты. Запустите кто нибудь эту программу. 

Hr.Smartus
Offline
Зарегистрирован: 27.05.2017

Столкнулся с той же проблемой при использовании SoftwareSerial и SPI в подобном проекте (с библиотекой DMD/DMD2). При отключенном SPI в порт идет чистая информация из источника (другая ардуино), при включенных обоих библиотеках в софт.сериалпорт летит мусор.
Пришлось отказаться от SoftwareSerial и работать с обычным UART. Не так удобно конечно, но иначе не получается)

Находил упоминание о библиотеке AltSerial, но проверять не было времени. Попробуйте, может кому-то поможет.

// AltSoftSerial always uses these pins:
//
// Board          Transmit  Receive   PWM Unusable
// -----          --------  -------   ------------
// Teensy 3.0 & 3.1  21        20         22
// Teensy 2.0         9        10       (none)
// Teensy++ 2.0      25         4       26, 27
// Arduino Uno        9         8         10
// Arduino Leonardo   5        13       (none)
// Arduino Mega      46        48       44, 45
// Wiring-S           5         6          4
// Sanguino          13        14         12