Author Topic: TinyI2C_LCD  (Read 67178 times)

boxtec-support

  • freakyfriday
  • Hero Member
  • *
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: TinyI2C_LCD
« Reply #15 on: July 07, 2013, 11:31:19 AM »
Hallo Pylon,

Du bist als Collaborator eingeladen.
@microtherion: Danke für den Hinweis, ich selber bin wie gesagt völliger git-N00b. Ich stör mich aber immer dran, wenn ich von einem Projekt 7 Repos finde und nicht recht weiss welches aktuell ist und am Ende den Code vergleichen muss. Ich vermute bei der Anzahl Commiter hier ist das noch etwas Overkill, sehe aber den Sinn durchaus wenn wir von z.B. 5 Hauptentwicklern und 20 freiwilligen reden.

Das mit der I2C Adresse im EEPROM finde ich eine hervorragende Idee. Ich hatte mir lange überlegt einen I/O Pin mit Jumper dazu zu verwenden, aber dann ging der letzte freie für die Hintergrundbeleuchtung drauf und 2 Adressen zur Auswahl wären ja auch nicht übermässig berauschend gewesen.
Bzgl. I2C: In zwei Situation hatte ich solche Probleme:
  • Wenn der ISP Programmer noch angeschlossen ist
  • Mit 2 Displays auf dem Bus ohne externe Pullups (versuchs mal mit einem 1k-10k Pullup auf dem I2C Bus)
Zwischendurch musste ich auch alles mal stromlos machen und eins nach dem anderen wieder versorgen, gelegentlich hängen die Slaves irgendwo wartenderweise fest und lassen sich nicht mehr anders zu einem Neustart bewegen.

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #16 on: July 07, 2013, 08:58:44 PM »
Hallo Christoph,

Quote
Bzgl. I2C: In zwei Situation hatte ich solche Probleme:

    Wenn der ISP Programmer noch angeschlossen ist
    Mit 2 Displays auf dem Bus ohne externe Pullups (versuchs mal mit einem 1k-10k Pullup auf dem I2C Bus)

Zwischendurch musste ich auch alles mal stromlos machen und eins nach dem anderen wieder versorgen, gelegentlich hängen die Slaves irgendwo wartenderweise fest und lassen sich nicht mehr anders zu einem Neustart bewegen.

Ich habe das Problem gefunden: der Tiny hatte sich verabschiedet bevor ich auf's Display geschaut hatte. Nachdem ich den Delay im Test-Sketch auf 1 Sek. raufgesetzt hatte, lief er stundenlang durch, ohne die geringsten Probleme zu zeigen.

Ich hatte mir erlaubt, das Projekt in eine File-Struktur zu giessen und im Git-Repo einzuchecken. Die neuste Version erlaubt auch schon die Änderung der Adresse, auch wenn ich das noch nicht getestet habe.

Ich werde versuchen, möglichst viel Code aus dem Interrupt-Handler herauszulösen und in den Loop zu verschieben, damit sollten wir die Race-Condition in den Griff kriegen (hoffe ich zumindest).

boxtec-support

  • freakyfriday
  • Hero Member
  • *
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: TinyI2C_LCD
« Reply #17 on: July 07, 2013, 09:41:42 PM »
Hallo Pylon,

Juhu :) super, danke vielmals! Läuft seit 100, 200, 300s ohne Fehler durch.
Ich hab schon am Konzept gezweifelt und bin jetzt sehr erleichtert.

[Update]: Ich hab immer noch gelegentliche "Huster" drin, aber weitaus seltener und weniger vorhersehbar, der eingeschlagene Weg scheint auf jeden Fall das Problem anzugehen.
« Last Edit: July 07, 2013, 09:47:13 PM by boxtec-support »

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #18 on: July 09, 2013, 03:58:07 PM »
Hallo Christoph,

ich habe noch etwas aufgeräumt, den Code durchgesehen. TinyWireS ist nicht sehr sauber programmiert, einen unschönen Fehler habe ich hier gefixt:

Code: [Select]
    case USI_SLAVE_GET_DATA_AND_SEND_ACK:
      // put data into buffer
      // Not necessary, but prevents warnings
      rxHead = ( rxHead + 1 ) & TWI_RX_BUFFER_MASK;
      // check buffer size
      if (rxHead == rxTail) {
          // overrun
          rxHead = (rxHead + TWI_RX_BUFFER_SIZE - 1) & TWI_RX_BUFFER_MASK;
      } else {
        rxBuf[ rxHead ] = USIDR;
      }
      // next USI_SLAVE_REQUEST_DATA
      overflowState = USI_SLAVE_REQUEST_DATA;
      SET_USI_TO_SEND_ACK( );
      break;

Das kommt ganz am Schluss von usiTwiSlave.c hin und stellt sicher, dass der Ringbuffer nicht sich selbst überholt. Eigentlich müsste man ein NACK zurückgeben, wenn der interne Buffer voll ist, aber das lassen wir mal für zukünftige Versionen.

Sehr unschön ist auch, dass der onReceive-Handler sowohl aus dem Interrupt-Kontext, als auch aus dem normalen loop()-Kontext aufgerufen wird. Das verhindert eigentlich eine saubere Programmierung. Bei uns ist das aber (im Moment) nicht relevant.

Ich habe auch noch etwas Debugging-Code eingebaut, die Geschwindigkeit etwas hochgeschraubt und festgestellt, dass die "Huster" bei der Übertragung über I2C passieren, der Master kriegt dann auch ein NACK zurück, könnte also die Übertragung nochmals wiederholen. Wie und warum es dazu kommt, ist mir noch nicht ganz klar, das untersuche ich aber noch.

boxtec-support

  • freakyfriday
  • Hero Member
  • *
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: TinyI2C_LCD
« Reply #19 on: July 09, 2013, 05:58:17 PM »
Hallo Pylon,

Die Änderung  den Buffer auf Überlauf zu prüfen macht absolut Sinn. Ich hab das dem Autor der ursprünglichen TinyWireS Library (brohogan) vorgeschlagen. Aber da dies hier "nur" die Firmware für den ATtiny betrifft würde ich vorschlagen, die modifizierte TinyWireS wird einfach Teil der Firmware und kommt auch ins Repo statt als externes Requirement. Da es eh eine Vielzahl von Forks gibt scheint mir das sinnvoll oder was meinst Du ?

Ich werd mich die nächsten Tage mal daran machen noch die eine oder andere noch fehlende Funktion einzubauen und ebenfalls den neuen Prototypen mit Hintergrundbeleuchtungssteuerung zu bestellen.
Gibts sonst noch Feedback bzgl. des PCBs was man für den nächsten Prototypen berücksichtigen sollte ?

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #20 on: July 09, 2013, 07:37:14 PM »
Hallo Christoph,

ich nehme an, das Board-Layout, das Du hier im Thread gepostet hast, ist bereits die neuere Version als die, die ich habe (dort ist D10 herausgeführt). Ansonsten habe ich keine Wünsche, aber dieser Pin ist ganz praktisch, damit ich Pulse für den Logic Analyzer generieren kann. Ich greife ihn momentan am Chip ab, aber das ist nicht wirklich "convenient"  :).

Ansonsten habe ich momentan keine Verbesserungsvorschläge.

Das Einbauen der TinyWireS-Sourcen macht sicher Sinn. Ich mache das noch und markiere es als Fork. Dann können wir auch die bereits erwähnten Erweiterungen später ohne Probleme anbringen.

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #21 on: July 09, 2013, 11:26:41 PM »
Ich habe den Grund für die "Huster" gefunden. Der Tiny kommt bei einigen ACK zu spät, SDA nach Masse zu ziehen, was einem NACK entspricht. Ich suche mal im Code von TinyWireS nach der Ursache.
Das Mehrfachsenden habe ich implementiert, seit einer halben Stunde hatte ich kein einziges falsch übertragenes Zeichen mehr.

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: TinyI2C_LCD
« Reply #22 on: July 09, 2013, 11:36:46 PM »
Salut Christoph,

kannst Du die Fritzing Source posten? Ich würde gerne das Design gegenchecken

Ciao, Mathias

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #23 on: July 10, 2013, 10:38:49 PM »
Ich habe das Problem gelöst. Die Aussetzer traten auf, weil einzelne I2C-Übertragungen vom Tiny ignoriert wurden. Mittels Debug-Pin (D10) konnte ich das Timing nachvollziehen und sah, dass der Start-Condition-Interrupt-Handler erst aufgerufen wird, wenn die Condition schon nicht mehr existiert.



Da dies nur in einigen Fällen eintritt, es aber meist korrekt funktioniert, musste es sich um eine Race-Condition handeln. Der einzig plausible Grund dafür musste der Timer-Interrupt für die millis()-Funktion sein. Mit diesem auskommentiert (in wiring.c), konnte ich keine einzige Fehlübertragung mehr feststellen.

Wir müssten jetzt entscheiden, ob wir die Mehrfachübertragungen in Kauf nehmen oder die Firmware ohne Timer-Interrupt kompilieren wollen.

Edit: Das Zulassen von verschachtelten Interrupts im Millis-Handler genügt auch, damit funktioniert die millis()-Funktion immer noch.

Code-Ausschnitt:
Code: [Select]
ISR(MILLISTIMER_OVF_vect)
{
  sei(); // enable nested interrupts
  // copy these to local variables so they can be stored in registers
  // (volatile variables must be read from memory on every access)
  unsigned long m = millis_timer_millis;
  unsigned char f = millis_timer_fract;
« Last Edit: July 10, 2013, 10:59:51 PM by pylon »

boxtec-support

  • freakyfriday
  • Hero Member
  • *
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: TinyI2C_LCD
« Reply #24 on: July 11, 2013, 04:59:16 PM »
Sensationell, bestätige, dass die Fehler komplett verschwunden sind (auch nach 30min noch keiner).
Danke auch für die Beschreibung des Analysewegs, das ist sehr hilf- und lehrreich.

Ich bin definitiv der Meinung, dass wenn das Problem so komplett gelöst wird, dies sicherlich besser ist als Mehrfachübertragungen in Kauf zu nehmen. Auch wenn es die Suppe wahrscheinlich in 999 von 1000 Fällen nicht fett macht, dass der Master eine Wiederholung machen muss dreht dieser für die Wiederholung ein paar Cycles mehr.
Aber was wäre der einfachste Weg um die entsprechende ISR Funktion in wiring.c zu überschreiben/ersetzen ?

@Pylon: Das Layout, dass ich hier gepostet habe ist das aktuelle. Ich werde es noch etwas kleiner machen, damit es auch bei sehr kleinen LCD Modulen keinen Überhang gegenüber dem Display gibt.

@Mathias: Re: Fritzing: Ich würds gerne gleich ins git repo einchecken, ist es ok wenn ich es in ein neues Verzeichnis board importiere/commite ?

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #25 on: July 11, 2013, 05:16:45 PM »
Quote
Aber was wäre der einfachste Weg um die entsprechende ISR Funktion in wiring.c zu überschreiben/ersetzen ?

Die in meinem vorherigen Post erwähnte Einfügung von "sei()" im wiring.c des tiny-Subbaums ist die einzige Methode, die mir in den Sinn kommt. Da es nur eine Zeile ist und diese Änderung auch bei anderen Tiny-Projekten keine Probleme bereiten sollte (sofern sie korrekt implementiert sind, also die IRQ-Handler kurz gehalten sind), würde ich es fix dort eintragen.
« Last Edit: July 11, 2013, 05:25:07 PM by pylon »

boxtec-support

  • freakyfriday
  • Hero Member
  • *
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: TinyI2C_LCD
« Reply #26 on: July 11, 2013, 05:25:40 PM »
Ok, dann mach ich das als Notiz ins Readme. Wers dann ohne die Änderung baut hat ja noch keine Probleme deswegen aber verliert zwischendurch vielleicht etwas Rechenzeit. Für uns beim Bespielen der ATtiny ist es kein Problem.

Ist das Verzeichnis board für die Designdatei(ein) für Dich ok ?

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: TinyI2C_LCD
« Reply #27 on: July 11, 2013, 07:24:26 PM »
Quote
Ist das Verzeichnis board für die Designdatei(ein) für Dich ok ?

Selbstverständlich.

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: TinyI2C_LCD
« Reply #28 on: July 11, 2013, 08:16:53 PM »
Salut,

"board" ist ok für mich. Ich habe das Ganze anhand der Platine in Eagle aufgesetzt und etwas entflochten. Ich möchte auch vorschlagen, die I2C pins so anzuordnen, wie es auf anderen Boards der Fall ist: GND,Vcc,SDA,SCL und Befestigungslöcher (M3) anbringen.

@pylon: Ich bin tief beeindruckt, wie Du das Problem gelöst hast. Ich werde mich wieder der Auslese eines lCCD widmen und gegebenenfalls versuchen, Dich für das Debuggen zu begeistern (lCCD gibt es gratis dazu)

Ciao, Mathias

boxtec-support

  • freakyfriday
  • Hero Member
  • *
  • Posts: 787
  • Karma: +15/-0
    • Boxtec Web
Re: TinyI2C_LCD
« Reply #29 on: July 11, 2013, 09:48:14 PM »
Das Fritzing File ist im Repo.

Quote
@pylon: Ich bin tief beeindruckt, wie Du das Problem gelöst hast.
Dem kann ich mich nur anschliessen!

 

anything