INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Nano als I/O Erweiterung für den RPi
12.01.2020, 20:02
Beitrag #25
RE: Nano als I/O Erweiterung für den RPi
In welchen Abständen planst Du die Daten im EEPROM zu aktualisieren?
Dir ist bekannt, dass die Anzahl der Schreibzyklen begrenzt ist?

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.01.2020, 20:09
Beitrag #26
RE: Nano als I/O Erweiterung für den RPi
ja genau deshalb gibt es eine Speicher Befehl und es wird nicht bei jeder Änderung der Config das EEProm aktualisiert.
So kann man in ruhe Testen ohne das das zu Problem wird.

Dann wann es Notwenig ist aus dem Backend Service des PI wahrscheinlich gar nicht.
Planung ist so wenn der CarPC eingerichtet ist wird sich da nie wieder was ändern.

Mein Projekt
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.01.2020, 20:13
Beitrag #27
RE: Nano als I/O Erweiterung für den RPi
(12.01.2020 20:09)DerkleinePunk schrieb:  Planung ist so wenn der CarPC eingerichtet ist wird sich da nie wieder was ändern.
Ok. Sonst hätte ich zu einem FRAM geraten.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.01.2020, 11:42
Beitrag #28
RE: Nano als I/O Erweiterung für den RPi
Code:
#include <Wire.h>
#define SLAVE_ADDRESS 0x30
#include <EEPROM.h>
#include "EEPROMHelper.h"
#include "config.h"
#include "DebugPrinter.h"

//Pins
#define INT 2
#define PWM1 3
#define DIGI0 4
#define DIGI1 5
#define DIGI2 6
#define DIGI3 7
#define DIGI4 8
#define DIGI5 9
#define DIGI6 10
#define PWM2 11
#define DIGI7 12
#define HISTORYCOUNT 10
//#define LED 13 LED_BUILTIN

word sensorWert = 0x0000;
word lastAD[6] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
word adHistory[6][HISTORYCOUNT];
word lastDIGIValue = 0;

config_t configuration;
unsigned long previousMillis = 0;

void saveConfig() {
  unsigned long crc = crc32(configuration);
  DebugPrinter.print(F("crc: 0x"));
  DebugPrinter.println(crc, HEX);
  EEPROM.put(0, crc);
  EEPROM.put(4, configuration);
}

void initializeEEPROM() {
  unsigned long crc;
  EEPROM.get(0, crc);
  EEPROM.get(4, configuration);
  unsigned long crcProm = eeprom_crc32(4, sizeof(configuration));
  DebugPrinter.print(F("crc: 0x"));
  DebugPrinter.println(crc, HEX);
  DebugPrinter.print(F("crcProm: 0x"));
  DebugPrinter.println(crcProm, HEX);
  if((configuration.progd_flag == progdFlagDefault) && (crc == crcProm)) {
    DebugPrinter.println(F("EEPROM good"));
    return;
  }
  DebugPrinter.print(F("progd_flag: 0x"));
  DebugPrinter.println(configuration.progd_flag, HEX);
  configuration.progd_flag = progdFlagDefault;
  configuration.interval = 1000;
  configuration.enableAD = 0xFF;
  configuration.enableDIGI = 0xFF;
  configuration.outputDIGI = 0x00;
  saveConfig();
  DebugPrinter.println(F("EEPROM init done"));
}

void configDIGI() {
  if(bitRead(configuration.outputDIGI, 0) == 1) {
     DebugPrinter.println(F("Set DIGI0 to OUTPUT"));
     pinMode(DIGI0, OUTPUT);
  } else {
     DebugPrinter.println(F("Set DIGI0 to INPUT"));
     pinMode(DIGI0, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 1) == 1) {
     pinMode(DIGI1, OUTPUT);
  } else {
     pinMode(DIGI1, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 2) == 1) {
     pinMode(DIGI2, OUTPUT);
  } else {
     pinMode(DIGI2, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 3) == 1) {
     pinMode(DIGI3, OUTPUT);
  } else {
     pinMode(DIGI3, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 4) == 1) {
     pinMode(DIGI4, OUTPUT);
  } else {
     pinMode(DIGI4, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 5) == 1) {
     pinMode(DIGI5, OUTPUT);
  } else {
     pinMode(DIGI5, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 6) == 1) {
     pinMode(DIGI6, OUTPUT);
  } else {
     pinMode(DIGI6, INPUT);
  }
  if(bitRead(configuration.outputDIGI, 7) == 1) {
     pinMode(DIGI7, OUTPUT);
  } else {
     pinMode(DIGI7, INPUT);
  }
}

void setup() {
  DebugPrinter.begin(9600);
  // Define the LED pin as Output
  pinMode (LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  pinMode (INT, OUTPUT);
  // PWM as Ouputs
  pinMode(PWM1, OUTPUT);
  pinMode(PWM2, OUTPUT);
  //muss nicht sein weil Default so Aber ich finde es besser wenn es da steht
  pinMode(DIGI0, INPUT);
  pinMode(DIGI1, INPUT);
  pinMode(DIGI2, INPUT);

  //Setup PWM
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
  //490.196Hz Timer 2 prescaler (64)
  TCCR2B = _BV(CS22);
  //30.637Hz Timer 2 prescaler (1024)
  //TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
  
  OCR2A = 0xFF; // 100%
  OCR2B = 0xFF; // 100%
  
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  initializeEEPROM();
  configDIGI();
  DebugPrinter.printConfig(configuration);
  for(byte x=0; x < 6; x++) {
    for(byte y=0; y < HISTORYCOUNT; y++) {
      adHistory[x][y] = 0x00;
    }
  }
  DebugPrinter.println(F("Boot Done"));
}

word getDigiValue(){
  word value = 0;
  if(bitRead(configuration.enableDIGI, 0) == 1 && bitRead(configuration.outputDIGI, 0) == 0) {
    //DebugPrinter.println(F("Read DIGI0"));
    value |= digitalRead(DIGI0);
  }
  if(bitRead(configuration.enableDIGI, 1) == 1 && bitRead(configuration.outputDIGI, 1) == 0) {
    value |= digitalRead(DIGI1) << 1;
  }
  if(bitRead(configuration.enableDIGI, 2) == 1 && bitRead(configuration.outputDIGI, 2) == 0) {
    value |= digitalRead(DIGI2) << 2;
  }
  if(bitRead(configuration.enableDIGI, 3) == 1 && bitRead(configuration.outputDIGI, 3) == 0) {
    value |= digitalRead(DIGI3) << 3;
  }
  if(bitRead(configuration.enableDIGI, 4) == 1 && bitRead(configuration.outputDIGI, 4) == 0) {
    value |= digitalRead(DIGI4) << 4;
  }
  if(bitRead(configuration.enableDIGI, 5) == 1 && bitRead(configuration.outputDIGI, 5) == 0) {
    value |= digitalRead(DIGI5) << 5;
  }
  if(bitRead(configuration.enableDIGI, 6) == 1 && bitRead(configuration.outputDIGI, 6) == 0) {
    value |= digitalRead(DIGI6) << 6;
  }
  if(bitRead(configuration.enableDIGI, 7) == 1 && bitRead(configuration.outputDIGI, 7) == 0) {
    value |= digitalRead(DIGI7) << 7;
  }
  return value;
}

void setAnswerBuffer(byte registerToRead) {
  switch(registerToRead) {
    case 0x00:
      sensorWert = lastAD[0];
      break;
    case 0x01:
      sensorWert = lastAD[1];
      break;
    case 0x02:
      sensorWert = lastAD[2];
      break;
    case 0x03:
      sensorWert = lastAD[3];
      break;
    case 0x04:
      sensorWert = lastAD[4];
      break;
    case 0x05:
      sensorWert = lastAD[5];
      break;
    case 0x06:
      sensorWert = OCR2A;
      break;
    case 0x07:
      sensorWert = OCR2B;
      break;
    case 0x08:
      sensorWert = getDigiValue();
      break;
    default:
      DebugPrinter.println(F("Unkown Register"));
  }
}

void setPollingInterval(byte intervalInt) {
  if(intervalInt <= 0) {
    DebugPrinter.print(F("ignore new polling interval"));
    return;
  }
  configuration.interval = intervalInt * 1000;
  DebugPrinter.print(F("set Interval to "));
  DebugPrinter.println(configuration.interval);
}

void setPWM1Time(byte value) {
  OCR2A = value;
  DebugPrinter.print(F("set PWM1Time to "));
  DebugPrinter.println(value);
}

void setPWM2Time(byte value) {
  OCR2B = value;
  DebugPrinter.print(F("set PWM2Time to "));
  DebugPrinter.println(value);
}

void changeDIGI(byte value) {
  configuration.outputDIGI = value;
  configDIGI();
}

void receiveData(int byteCount){
  digitalWrite(LED_BUILTIN, HIGH);
  if(byteCount < 1) {
     DebugPrinter.print(F("ignore I²C Message"));
     digitalWrite(LED_BUILTIN, LOW);
     return;
  }
  byte registerNumber = Wire.read();
  byte registerValue = 0x00;
  bool valueSet = false;
  if(byteCount >= 2) {
      registerValue = Wire.read();
      valueSet = true;
  }
  DebugPrinter.print(F("i²c received register: 0x"));
  DebugPrinter.print(registerNumber, HEX);
  DebugPrinter.print(F(" value: 0x"));
  DebugPrinter.print(registerValue, HEX);
  DebugPrinter.println();
  sensorWert = 0x0000;
  switch(registerNumber) {
    case 0x00:
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x06:
    case 0x07:
    case 0x08:
      setAnswerBuffer(registerNumber);
      break;
    case 0x10:
      if(valueSet) {
        setPollingInterval(registerValue);
      };
    case 0x11:
      if(valueSet) {
        setPWM1Time(registerValue);
      } else {
        sensorWert = 0xFFFF;
      }
      break;
    case 0x12:
      if(valueSet) {
        setPWM2Time(registerValue);
      } else {
        sensorWert = 0xFFFF;
      }
      break;
    case 0x13:
      if(valueSet) {
        configuration.enableAD = registerValue;
      } else {
        sensorWert = 0xFFFF;
      }
      break;
    case 0x14:
      if(valueSet) {
        configuration.enableDIGI = registerValue;
      } else {
        sensorWert = 0xFFFF;
      }
      break;
    case 0x15:
      if(valueSet) {
        changeDIGI(registerValue);
      } else {
        sensorWert = 0xFFFF;
      }
      break;
    case 0xE0:
      DebugPrinter.setEnabled(!DebugPrinter.getEnabled());
      break;
    case 0xF0:
      saveConfig();
      DebugPrinter.printConfig(configuration);
      break;
    default:
      sensorWert = 0xFFFF;
      break;
  }
  digitalWrite(LED_BUILTIN, LOW);
}

// callback for sending data
void sendData(){
  digitalWrite(LED_BUILTIN, HIGH);
  Wire.write(lowByte(sensorWert));
  Wire.write(highByte(sensorWert));
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(INT, LOW);
}

void traceHistory(byte adress) {
  DebugPrinter.print(F("AD"));
  DebugPrinter.print(adress, HEX);
  DebugPrinter.print(F(" History:"));
  for(byte y=0; y < HISTORYCOUNT; y++) {
    DebugPrinter.print(F(" 0x"));
    DebugPrinter.print(adHistory[adress][y], HEX);
  }
  DebugPrinter.println();
}

bool readAd(byte adress) {
  bool valueChanged = false;
  if(bitRead(configuration.enableAD, adress) == 1) {
    word adValue = 0x00;
    //AD4 und AD5 Belegt durch I²C
    switch(adress) {
      case 0x00:
        adValue = analogRead(A0);
        break;
      case 0x01:
        adValue = analogRead(A1);
        break;
      case 0x02:
        adValue = analogRead(A2);
        break;
      case 0x03:
        adValue = analogRead(A3);
        break;
      case 0x04:
        adValue = analogRead(A6);
        break;
      case 0x05:
        adValue = analogRead(A7);
        break;
    }
    for(byte y=1; y < HISTORYCOUNT; y++) {
      adHistory[adress][y-1] = adHistory[adress][y];
    }
    adHistory[adress][HISTORYCOUNT-1] = adValue;
    for(byte y=0; y < HISTORYCOUNT; y++) {
      adValue += adHistory[adress][y];
    }
    adValue = adValue / (HISTORYCOUNT + 1);
    if(adValue != lastAD[adress]) {
      lastAD[adress] = adValue;
      valueChanged = true;
      DebugPrinter.print(F("AD"));
      DebugPrinter.print(adress, HEX);
      DebugPrinter.print(F(" has Value: "));
      DebugPrinter.print(lastAD[adress], HEX);
      DebugPrinter.println();
    }
  }
}

bool readAds() {
  bool valueChanged = false;
  for(byte i = 0; i < 6; ++i) {
    if(readAd(i)){
      valueChanged = true;
    }
  }
  return valueChanged;
}

byte adMessCount = 0;

void loop() {
  bool valueChanged = false;
  const unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= (configuration.interval / HISTORYCOUNT)) {
    previousMillis = currentMillis;
    valueChanged = readAds();
    adMessCount++;
    if(adMessCount < (HISTORYCOUNT -1)) {
      valueChanged = false;
    } else {
      adMessCount = 0;
    }
  }
  if(valueChanged) {
    digitalWrite(INT, HIGH);
  } else {
    if(lastDIGIValue != getDigiValue()) {
      lastDIGIValue = getDigiValue();
      digitalWrite(INT, HIGH);
    }
  }
}

Ich bin jetzt so weit zu frieden und es scheint auch alles bis dato zu klappen.
Was ich aber nicht verstehe ist:
Wenn ich die Seriale Übertragung auf 38400 Baud stelle oder zu viel Serial übertrage dann geht nicht mehr viel I²C lese / schreib fehler sehe keine Ausgaben im Terminal Programm. Weder in dem der Arduino IDE noch einem Externen. Das würde ich gerne noch verstehen.

Mein Projekt
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
18.01.2020, 11:53
Beitrag #29
RE: Nano als I/O Erweiterung für den RPi
Was ist DebugPrinter?

Ich arbeite generell auf Seriell mit Baudraten von 115200 und habe damit keine Probleme.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.01.2020, 10:32
Beitrag #30
RE: Nano als I/O Erweiterung für den RPi
Flashen tut er mit 56K das geht auch.

Code:
#include "DebugPrinter.h"
#include "HardwareSerial.h"

DebugPrinter_::DebugPrinter_() {
  enableDebug = true;
}

void DebugPrinter_::begin(int speed, bool enabled){
  Serial.begin(speed);
  enableDebug = enabled;
}

size_t DebugPrinter_::write(uint8_t k) {
  if(!enableDebug) return 0;
  return Serial.write(k);
}

void DebugPrinter_::printConfig(config_t config) {
   if(!enableDebug) return;
  
   print(F("progd: 0x"));
   println(config.progd_flag, HEX);

   print(F("enableAD: 0x"));
   println(config.enableAD, HEX);
  
   print(F("enableDIGI: 0x"));
   println(config.enableDIGI, HEX);

   print(F("outputDIGI: 0x"));
   println(config.outputDIGI, HEX);

   print(F("interval: "));
   println(config.interval);
}

bool DebugPrinter_::getEnabled(){
  return enableDebug;
}

void DebugPrinter_::setEnabled(bool enabled){
  enableDebug = enabled;
}

DebugPrinter_ DebugPrinter;

Mein Projekt
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.01.2020, 11:42 (Dieser Beitrag wurde zuletzt bearbeitet: 19.01.2020 11:44 von DerkleinePunk.)
Beitrag #31
RE: Nano als I/O Erweiterung für den RPi
jetzt wird es komisch

Code:
#ifndef DebugPrinter_h
#define DebugPrinter_h

#include <Print.h>
#include "config.h"

class DebugPrinter_ : public Print
{
  private:
    bool enableDebug = true;
  public:
    DebugPrinter_();
    void begin(unsigned long baud, bool enabled = true);
    size_t write(uint8_t k);
    void printConfig(config_t config);
    bool getEnabled();
    void setEnabled(bool enabled);
};

extern DebugPrinter_ DebugPrinter;

#endif //DebugPrinter_h

Code:
#include "DebugPrinter.h"
#include <Arduino.h>  // for type definitions

DebugPrinter_::DebugPrinter_() {
  enableDebug = true;
}

void DebugPrinter_::begin(unsigned long baud, bool enabled){
  Serial.begin(baud);
  enableDebug = enabled;
}

size_t DebugPrinter_::write(uint8_t k) {
  if(!enableDebug) return 0;
  return Serial.write(k);
}

void DebugPrinter_::printConfig(config_t config) {
   if(!enableDebug) return;
  
   print(F("progd: 0x"));
   println(config.progd_flag, HEX);

   print(F("enableAD: 0x"));
   println(config.enableAD, HEX);
  
   print(F("enableDIGI: 0x"));
   println(config.enableDIGI, HEX);

   print(F("outputDIGI: 0x"));
   println(config.outputDIGI, HEX);

   print(F("interval: "));
   println(config.interval);
}

bool DebugPrinter_::getEnabled(){
  return enableDebug;
}

void DebugPrinter_::setEnabled(bool enabled){
  enableDebug = enabled;
}

DebugPrinter_ DebugPrinter;

Jetzt kann ich zu mindestens mal die Baudrate um schalten ohne das nicht mehr geht.
Was ich jetzt auch mal gemacht habe weil es besser rein passt. Nicht mit der IDE Compiliert sondern mit PlatformIO (Ich benutze VS Code für die C++ auf dem PI)
Da kamen ein paar Warnungen die berechtigt sind. Aber in der Ardunio IDE habe ich die nie gesehen. Habe ich Einstellungen Übersehen ?
Der wohl Fatalste Fehler ist eine Funktion die vergisst was zurück zu geben...

Jemand eine Idee wie ich erkennen kann das die USB UART verbunden ist ?

Mein Projekt
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.01.2020, 11:57
Beitrag #32
RE: Nano als I/O Erweiterung für den RPi
(19.01.2020 11:42)DerkleinePunk schrieb:  Der wohl Fatalste Fehler ist eine Funktion die vergisst was zurück zu geben...
Welche Funktion "vergisst"? (Eher der Programmierer hat vergessen Wink )

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Schaltuhr Erweiterung 433Mhz Funk volvodidi 17 5.997 12.01.2020 14:50
Letzter Beitrag: hotsystems
  Arduino Nano, Sensoren und Nextion MotD 24 10.936 30.08.2018 10:42
Letzter Beitrag: hotsystems
  Laser mit arduino nano TTL modulieren Wranox 0 3.480 30.07.2015 15:38
Letzter Beitrag: Wranox
  Linienfolger mit Arduino Nano reenoh 16 12.887 27.05.2015 11:04
Letzter Beitrag: reenoh
Wink DSLR mit Arduino Nano steuern. Eichner 12 13.059 25.03.2015 17:27
Letzter Beitrag: Eichner
Rainbow RC Beleuchtungsmodul mit Arduino Nano Kyrill 7 8.099 15.03.2015 14:02
Letzter Beitrag: querkopf71
  Erweiterung für SD: fprintf_, fgets_, fscanf_ HaWe 0 1.978 08.03.2015 17:23
Letzter Beitrag: HaWe

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste