SPI und softwareserial parallel

Hallo,

Ich habe folgendes Problem:

Ich nutze für ein Projekt ein Display mit der RA8875 library: GitHub - sumotoy/RA8875: A library for RAiO RA8875 display driver for Teensy3.x or LC/Arduino's/Energia/Spark
sowie dieses CAN Modul: https://www.seeedstudio.com/Serial-CAN-BUS-Module-based-on-MCP2551-and-MCP2515.html

Beide Geräte funktionieren einwandfrei, solange sie einzeln an einem Arduino UNO betrieben werden.
Wenn allerdings beides parallel funktionieren soll, geht gar nichts mehr.

Ich vermute, dass es ein Problem in der seriellen Kommunikation gibt. Das Display läuft ganz normal über SPI am UNO und das CAN Board benötigt für die eigene Bibliothek die softwareserial Bibliothek.

Meine Vermutung ist, dass es zwischen den beiden Bibliotheken irgendein Problem gibt (timer o.ä.) und diese somit nicht parallel funktionieren können. Auf den ersten Blick und mit nur mittelmäßigen Kenntnissen hab ich in den Bibliotheken keinen offensichtlichen Fehler ausmachen können.

Hat damit schon jemand Erfahrungen gemacht?

Vielen Dank schonmal im Voraus!

Viele Grüße,
x0RRY

Du solltest nochmal beischreiben welche Pins du benutzt.

Für SPI die sechs ICSP pins und für das CAN Board A4 & A5. Wird aber nur zum Empfangen benötigt.

Alleine funktioniert alles ohne Probleme, nur eben wenn beide geichzeitig laufen sollen funktioniert nichts mehr. Deshalb eben meine Vermutung, dass der Fehler in der Kommunikation liegen muss.

x0RRY:
Für SPI die sechs ICSP pins und für das CAN Board A4 & A5. Wird aber nur zum Empfangen benötigt.

Alleine funktioniert alles ohne Probleme, nur eben wenn beide geichzeitig laufen sollen funktioniert nichts mehr. Deshalb eben meine Vermutung, dass der Fehler in der Kommunikation liegen muss.

Ok, A5 ist allerdings sehr ungewöhnlich, hatte da eher einen anderen Pin vermutet.
Viele Beschreibungen von SoftwareSerial nutzen Pin 11 und 12.

Da habe ich leider aktuell keine Idee.
Ich habe selbst mal in einem Testaufbau ein Display an ISP und SoftwareSerial für einen DFplayer genutzt.
Kann mich aber nicht an Probleme erinnern.

Edit:
Die Wire-Lib hast du nicht mit eingebunden ?

Verwendest Du softwareserial oder/und I2C?

x0RRY:
Für SPI die sechs ICSP pins und für das CAN Board A4 & A5. Wird aber nur zum Empfangen benötigt.

Alleine funktioniert alles ohne Probleme, nur eben wenn beide geichzeitig laufen sollen funktioniert nichts mehr. Deshalb eben meine Vermutung, dass der Fehler in der Kommunikation liegen muss.

Für SPI die sechs ICSP pins
Kann nicht sein.
Reicht nicht.

Vermutlich ist der Schaltplan auch zu 100% ok, so dass auch dieser im Verborgenen ruhen darf.

nur eben wenn beide geichzeitig laufen sollen
Da dein Programm fehlerfrei ist, gibt es keinen Grund dieses hier zu zeigen.

dass es zwischen den beiden Bibliotheken irgendein Problem gibt
Da wir alle ganz genau wissen, welche CAN Library du nutzt ....

Sorry, bin gerade unterwegs und bin mir bewusst, dass die Informationen etwas spärlich sind.
Dachte nur, dass es eventuell ein bekanntes Problem in der Kommunikation sein könnte.

Ich melde mich in 1-2 Stunden nochmal mit dem Code sowie der genauen pinbelegung.

CAN lib: GitHub - Longan-Labs/Serial_CAN_Arduino

So.

SPI CS: D10
CAN rx: A5

////////////////////////////////////////
// DISPLAY SETUP
////////////////////////////////////////

#include <SPI.h>
#include <RA8875.h>

#define RA8875_CS 10
#define RA8875_RESET 9

RA8875 tft = RA8875(RA8875_CS, RA8875_RESET);


////////////////////////////////////////
// CAN BOARD SETUP
////////////////////////////////////////

#include <Serial_CAN_Module.h>
#include <SoftwareSerial.h>

Serial_CAN can;

#define can_tx  A4           
#define can_rx  A5        


////////////////////////////////////////
// SETUP
////////////////////////////////////////

void setup()
{

  Serial.begin(9600);
  Serial.println("RA8875 start");
  tft.begin(RA8875_800x480);  

 //CAN Setup
    can.begin(can_tx, can_rx, 9600);      // tx, rx
    Serial.println("serial begin");


}   

////////////////////////////////////////
// FUNCTIONS
////////////////////////////////////////

//Power function for integers 
int ipow(int base, int exponent)
{
    int result = 1;
    for (;;)
    {
        if (exponent & 1)
            result *= base;
        exponent >>= 1;
        if (!exponent)
            break;
        base *= base;
    }
  return result;
}


void draw_seconds()
{
  //Print time in seconds
  tft.setTextColor(RA8875_BLACK,RA8875_YELLOW);
  tft.setCursor(50,380);
  tft.print("Time since start: ");
  tft.print(millis()/1000,DEC);
  tft.println(" seconds");
  tft.setTextColor(RA8875_WHITE,RA8875_BLACK);
}


////////////////////////////////////////
// CAN FUNCTIONS
////////////////////////////////////////

unsigned char datenKSG[8] = {0};
unsigned long id = 0x22E;

void canserial()
{
  if(can.recv(&id, datenKSG))
    {
        unsigned long value = 0;
        value = (datenKSG[2] + datenKSG[3]*ipow(16,2))/10; // reads out speed in km/h
        
        if (value != 0)
          {
            Serial.print(value);
            Serial.println(" km/h");
          }

        if (datenKSG[1] == 1)
          Serial.println("Licht ist an");

        if (datenKSG[0] == 1)
          Serial.println("Blinker links");

        if (datenKSG[0] == 2)
          Serial.println("Blinker rechts");

        if (datenKSG[0] == 3)
          Serial.println("Warnblinker");
    }
}


void loop()
{
  canserial(); 
  draw_seconds();
}

Das ganze funktioniert einwandfrei, wenn je eine der beiden Funktionen im loop auskommentiert ist, ansonsten nicht.
Sonst noch infos benötigt?

draw_seconds()

SoftwareSerial erwartet relativ ungestörte Interrupts.

Dein draw_seconds() feuert pausenlos mit roher Gewalt SPI Interrupts.

Falls du dafür Sorge tragen würdest, dass das Display nur upgedatet wird, wenn sich die Sekunde auch wirklich geändert hat, dann sollte sich die Situation bessern.

Evtl auf einen Arduino Mega aufrüsten, der hat 4 Hardwareserial.

Ich hab einen anderen Verdacht.

RAM ist verbraucht.
Durch die vielen xx.print("text" bzw xx.println("text") wird RAM verbraucht. Ich nahme mal an daß auch die Bibliotheken sich kräftig am RAM bedienen.

Versuch mal das F()-Makro

xx.print(F("text")); Das macht daß Texte von FLASH-Speicher direckt ausgegeben werden und nicht über RAM gepuffert werden.

Ein MEGA als Test könnte wegen dem 4-fachen RAM auch Besserung bringen.

Wenn Du ein wenig suchst dann findest Du auch eine Funktion die Während der Ausführung des Sketches den RAM-Verbrauch ausgibt.

Vieleicht weiß jemand einen Link dazu.

Grüße Uwe

freeMemory

Vielen Dank für die Antworten. Ich habe das draw_seconds entfernt und den scetch etwas geupdated.

Ich lese jetzt nurnoch die Geschwindigkeit aus und printe diese direkt auf dem Bildschirm:

unsigned char datenKSG[8] = {0};
unsigned long id = 0x22E;
unsigned long value = 0;

void canserial()
{
  if(can.recv(&id, datenKSG))
    {
        value = (datenKSG[2] + datenKSG[3]*ipow(16,2))/10; // reads out speed in km/h
        
        if (value != 0)
          {
            Serial.print(value);
            Serial.println(" km/h");
            
            tft.setTextColor(RA8875_BLACK,RA8875_YELLOW);
            tft.setCursor(50,380);
            tft.print("value");
          }
    }
}


void loop()
{
  canserial(); 
}

Ich habe davor auch noch etwas mit anderen Funktionen im loop experimentiert, aber da hat der Arduino sich meist selbst "resetted" und ist zurück in das setup gesprungen und dort stecken geblieben.

Als ich allerdings die tft.print Funktionen in meiner canserial() Funktion aufgerufen habe, lief der scetch für 10-15 Sekunden, bevor sich alles aufgehängt hat. Ist da das RAM Problem am plausibelsten?

Ich werde die ganzen Vorschläge mal morgen testen und Rückmeldung geben. Ein Mega wäre auch eine Überlegung Wert.

Ich habe davor auch noch etwas mit anderen Funktionen im loop experimentiert, aber da hat der Arduino sich meist selbst "resetted" und ist zurück in das setup gesprungen und dort stecken geblieben.

Als ich allerdings die tft.print Funktionen in meiner canserial() Funktion aufgerufen habe, lief der scetch für 10-15 Sekunden, bevor sich alles aufgehängt hat. Ist da das RAM Problem am plausibelsten?

Durchaus möglich.

Hallo,

Sorry für die späte Antwort.

Ich habe den RAM ausgelesen (mehr als genug verfügbar), das F()-Makro verwendet und benutze testweise einen Arduino Mega. Bisher allerdings keine Besserung.

Bisher allerdings keine Besserung.

Der nächst häufige Fehler wäre die "Array Bereichsüberschreitung".
Und/Oder Zeiger, welche in die Wiese zeigen.