DS3231 mit Systemzeit von PC aktualisieren

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
'geht das auch einfacher d.h. z.B. in etwa Tag = val(left(Datum,2)) ohne zusätzliche Hilfsbytes?
Ja, aber ob das mit Bascom-Mitteln selbst einfach im Sinne des Controllers UND Programmierers geht, weiß ich nicht.
Jeder der beiden Strings hat 'ne definierte Struktur, und liegt irgendwo im SRAM (genau genommen zeigt die Veriable auf die erste Adresse, die der String im SRAM belegt. Jedes Zeichen dieses Strings belegt genau ein Byte, in Form eines ASCII-Code-Zeichens. In Deinem Beispiel (Datum) oben steht also irgendwo im SRAM:
"1""2"".""0""1"".""2""0""2""0"ASCII-Null
0x31​
0x32​
0x2E​
0x30​
0x31​
0x2E​
0x32​
0x30​
0x32​
0x30​
0x00​
Und was ist Dein eigentliches Ziel?
Die RTC zu stellen, Du brauchst gepackte BCDs.
Im Tages-Register brauchst Du die Zehner und einer der "12", die "1" soll ins High-Nibble, die "2" ins Low-Nibble.
Das da oben steht also "als String" irgendwo im SRAM, die Variable Datum zeigt auf das erste Zeichen. Du willst aber nicht mit den ASCII-Symbolen rechnen, sondern mit den Codes, die in Wirklichkeit im Speicher stehen. Bytes.
Du brauchst also einen Zeiger auf diese Adresse(n), den Du in Bascom als Bytevariable(n) verwenden kannst - ein virtuelles Array of Byte. Virtuell, weil es eben gar keine neue Variable ist, sondern nur ein anderer Griff an derselben Variable


CodeBox BascomAVR
Dim Datum_byte(10) As Byte At Datum Overlay

Damit kannst Du also auf die ASCII-Codes des Strings als Bytes zugreifen.
Bauen wir also mal die Variable Tag zusammen:
Um aus den ASCII die reinen Zahlenwerte zu bekommen, mußt Du 0x30 abziehen.


CodeBox BascomAVR
Tag = Datum_byte(1) - 0x30

Die Zehner müssen allerdings ins obere Nibble geswapt werden.


CodeBox BascomAVR
Swap Tag

Anschließend addieren wir den ASCII der einer drauf.


CodeBox BascomAVR
Tag = Tag + Datum_byte(2)

Und ziehen hier auch nochmal 0x30 ab


CodeBox BascomAVR
Tag = Tag - 0x30

Also zusammen:


CodeBox BascomAVR
Tag = Datum_byte(1) - 0x30
Swap Tag
Tag = Tag + Datum_byte(2)
Tag = Tag - 0x30

Als Ergebnis hast Du dann die 0x23, die in Register 0x04 der RTC zu schreiben wären.

Tricky wird allerdings die Sache mit dem Wochentag, der ja auch irgendwie durch den PC übermittelt werden müßte. Nur mit der Eingabeaufforderung seh ich da grad keinen Weg
 
Zuletzt bearbeitet:

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Halo LotadaC

Danke für den Tipp, das habe ich auch verstanden. Dadurch spare ich Variablen ein.
Über den Wochentag habe ich mir auch schon meine Gedanken gemacht, da ist sicher etwas mehr Aufwand nötig.
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Man könnte statt der neuen Variable Tag auch einfach Datum_byte(1) verwenden (was natürlich den String überschreibt)

Für den Wochentag hab ich auch noch'n Ansatz... später.
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Danke, werde das heute Abend mal testen.
 

fredred

Mitglied
1 Okt 2015
76
2
7
Hallo DS1074,

hatte fast alle Fragen zum Thema RTC Uhr in https://www.makerconnect.de/index.php?threads/i2c-tm1637-rtc-1307.4288/post-45152 beantwortet Hyperlink entfernt siehe direkt im Forum
Im Anhang auch ein kommentierter Basiccode „Uhr mit DS1307-LED-0.bas“ da sollten schon mehr Antworten drin sein wie die, die bis jetzt gestellten Fragen( automatische. Zeitkorrektur, Zeitumstellung manuelle Einstellungen u.s.w) War wohl gleich zu viel und auch noch keine Lösung drin für: „mit ds3231-mit-systemzeit-von-pc-aktualisiere“. Hab mal eine Einfache erstellt.
Bild2.jpg
Einfach = eine COM- Verbindung herstellen HT starten und ein String an den Controller senden. Könnte so aussehen und
Bild5.jpg
P.S. Für meinen Datenlogger nutze ich gleich die SD- Karte um auf diesen neue Parameter zu schreiben ohne den Controller neu zu flashen. Erstelle in aller Ruhe und im Klartext am PC alles was geändert werden soll( auch die für Programmablauf nötig sind). Mit einsetzen der Karte wird µC Ablauf gestoppt alles Neue überschrieben und ab geht die Post wieder. Ist halt eine Systeminit.


CodeBox BascomAVR

'****** Variablen mit COM - Terminal setzen ***********
'*****     Arbeitet sozusagen im Hintergrund      *****
'**  Hauptschleife wird nur kurz gestoppt wenn N>0   **
'**     bis zu 255 Byte mit einem Ruck empfangen     **
'**  Abgleich könnte als Potokoll bezeichnet werden  **
'**   Aktuell 5 Blöcke a 5 Zeichen = 25 Byte + 5 Tz  **
'**       sind 30 Byte reserviert                    **
'**  also noch viel Luft nach Oben                   **
'**  Sendestring muss nicht 27 Byte und Block nicht  **
'**  5 Byte Länge haben.Ist hier nur als Maximum     **
'**  eingestellt.                                    **
'******** (c)fredred 2015 Ver Uart_1 ******************

$regfile = "M32def.dat"
$crystal = 16000000
$baud = 9600                                                '19200
$hwstack = 100
$swstack = 100
$framesize = 100

'µC auslesen
Print
Print "erstellt am  : " ; Version(1)
Print "Version Code : " ; Version(3)
Print
Wait 1

'## Einstellung für Uhr #########################

 Config Clock = soft                                      'ist ja kein HW- Clock aktiv
 Config Date = Dmy , Separator = .                         'German


'## Einstellung für Uart #########################

  Dim Sx As String * 27                                     'Stringlänge gesamt + Endzeichen
  Dim B(26) As Byte At Sx Overlay                           'Feld mit 24 Byte anlegen
  Dim N As Byte
  Dim Scount As Byte
  Dim Temps(5) As String * 5                                'Anzahl Blöcke/Länge vor Trennzeichen
  Dim Wert1 As String * 5                                   'Zeichen je Block
  Dim Wert2 As String * 5
  Dim Wert3 As String * 5
  Dim Wert4 As String * 5
  Dim Wert5 As String * 5
  Dim i As Byte
  Dim z As Byte

 '########################################

   Enable Urxc                                              'Uart Rx aktivieren
   Enable Interrupts
   On Urxc Onrxd                                            'ISR festlegen

   Z = 1

  Do
    For i = 1 To z  'für Test
     Wait 1
     Print "warte  " ;i ; "   Sekunden"
    Next

    If N > 16 Then ' ist Anzahl empfangener Zeichen
      'Hinweis: N sollte immer 1Byte kleiner sein als die min. Anzahl
      'der Sendebyte. Für Test auch N > 0 möglich.
        Print "String =  " ; Sx                             'für Test
        Print "N = " ; N                                    'für Test
        Gosub Abgleich
          N = 0         'Zähler zurücksetzen
       Print
       Print "Info = " ; wert1                               'für Test
       Print "Stunde = " ; Val(wert2)                        'für Test
       Print "Minute = " ; Val(wert3)                        'für Test
       Print "Sekunde = " ; Val(Wert4)                        'für Test
       Print "Waitschleife = " ; Val(Wert5)

       Z = Val(Wert5)

    End If

     'Dein Programm
       Print "******************************"               'für Test
       Print "mache meine eigentliche Arbeit"               'für Test
       Print "******************************"               'für Test
       Print "..............."                              'für Test
       Print "Blablabla"                                    'für Test
       Print "..............."                              'für Test
       Print

      Gosub Uhr
      Print "<< Uhrzeit<<  "; Time$ ; "  gestellt"
      Print " tickt natürlich [ hier ] nicht ist nur ein Beispiel zum stellen"

  Loop

'**** Trennzeichen kann jedes ASCII- Zeichen sein *************
 Abgleich:
   Scount = Split(sx , Temps(1) , "|")                      'zerlegt String
   Wert1 = Temps(1)                                         'Wert vor 1. Trennzeichen
   Wert2 = Temps(2)                                         'Wert vor 2. Trennzeichen
   Wert3 = Temps(3)                                         'Wert vor 3. Trennzeichen
   Wert4 = Temps(4)                                         'Wert vor 4. Trennzeichen
   Wert5 = Temps(5)                                         'Wert vor 4. Trennzeichen
  Return

  Uhr:
    _hour = Val(wert2)
    _min = Val(wert3)
    _sec = Val(wert4)

  Return

 'hier wird in Uart geschaut ob neue Byts gesendet wurden
  Onrxd:
   Incr N                                                   'Byte von UDR hochzählen
     B(n) = Udr
   Return


Vorab müssen nur Vereinbarungen getroffen werden. Ist wieder mal so ein Beispiel als Anregung. Soll zeigen muss nicht ein (eigenes) Protokoll entwickelt werden. Nur ein zuverlässiges nach Anforderungen nutzen.
Die Fragen:
"Warum dann nicht gleich den PC die fertigen gepackten BCDs generieren lassen, und diese an den Controller senden?
Warum überhaupt über den Controller und UART, und nicht gleich an die RTC selbst (eben über einen USB-Adapter/Bridge der/die I²C kann)?
Antwort:
Naja direkt vom PC ein I²C Protokoll schicken würde ich nicht empfehlen. Ist bekannt das bei der Verwendung von einem oder mehrere Bussysteme gleichzeitig, die Zeit (Takt) ein Problem, sein könnte. Die Laufzeiten der Teilnehmer müssen speziell bei I²C beachtet werden. So war ja auch für I²C gedacht oder?

P.S. Für meinen Datenlogger nutze ich gleich die SD- Karte um auf diesen neue Parameter zu schreiben ohne den Controller neu zu flashen. Erstelle in aller Ruhe und im Klartext am PC alles was geändert werden soll( auch die für Programmablauf nötig sind). Mit einsetzen der Karte wird µC Ablauf gestoppt alles Neue überschrieben und ab geht die Post wieder.
Ist halt eine Systeminit.

Sollte Ds1074 oder wer auch immer, mir erklären können, warum eine automatische Zeitkorregtur in Echtzeit nötig ist, erstelle ich mal ein paar Codeschnipsel in DOS oder mit eleganter Optik(Kacheln) mit WSV.
Sage aber vorab die dies wollen. Sind Spinner in meine Augen.
P.S. Kann nicht verstehen, warum die Raumzeit nicht mehr in Projekte als Master betrachtet wird. Der Volksmund sagt es doch schon „das schwächste Glied bestimmt den Halt der Kette“
Kann sein das ich als junger Mann mit 65 Jahren ein Schlaganfall = Flachspeicher kaputt hatte und nun schon ein paar Jahre Versuch einige alte Speicherplätze zu aktivieren.
Wie ihr lesen könnt hat es bis jetzt noch nicht gut funktioniert.

Mit freundlichen Grüßen


Mit freundlichen Grüßen
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Hallo an alle,

Danke für die vielen Antworten, vor allem auch Dir, fredred.

Mir geht es in erster Linie darum Chips wie z.B. der DS3213 und damit verbunden die I2C Programmierung verstehen zu lernen.
Ich bin auch über 60 und brauche halt etwas länger, um das alles zu kapieren, und ich will wissen, was ich mache.
Beim Arduino geht ja alles mit Lib's und wehe, es geht nicht.

In diesem Fall geht es mir darum, die Zeit, wenn nötig, aus der Systemzeit des PC's auszulesen, damit ich das nicht immer von Hand einstellen muss.
Mein DS3231 hat sich zwischendurch wieder mehrfach zurückgesetzt, was ich schon in #6 beschrieben habe.
Das Problem besteht also weiterhin.
Ansonsten reicht es mir, in einem Programm die aktuelle Uhrzeit auszulesen, um z.B. einen Datenlogger mit einem Zeit Stempel zu versehen.
Dazu muss der RTC aber erst mal stabil laufen. Das ist mein Hauptanliegen.

an LotadaC eine Frage:
ich habe deinen Beispiele code im Simulator getestet, bei mir kommt aber für den Tag 0x12 am Ende heraus und nicht 0x23.
Ist das nur ein Tippfehler?
Werde das ganze auch für den Monat und das Jahr noch testen.

Das mit dem Wochentag sehe ich im Moment nicht so tragisch.
Mir schwebt da was in folgender Form vor:
- Einen Wochentag fest einem Datum zuordnen z.B. 01.01.2000 (war ein Samstag)
- dann per Modulo 7 die entsprechenden Wochen ermitteln
- und dazu die Distanz zum aktuellen Tag dazu addieren.
Werde das mal testen.

Grüße an alle
 
Zuletzt bearbeitet:

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Das mit dem Wochentag sehe ich im Moment nicht so tragisch.
Mir schwebt da was in folgender Form vor:
Da muß der arme Mikrocontroller ja rechenen...
Für den Wochentag hab ich auch noch'n Ansatz... später.
Einfach mal'ne Batch-Datei mit folgendem Inhalt erstellen und testen:
Code:
@echo off
for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%%A
echo %time% %date% %daynumber%
Wenn das in der Eingabeaufforderung paßt, hängst Du hinten wieder das > com4 drann ;)
ich habe deinen Beispiele code im Simulator getestet, bei mir kommt aber für den Tag 0x12 am Ende heraus und nicht 0x23.
Ist das nur ein Tippfehler?
Ja genau, der Zwölfte war ja auch vorgegeben; aus dem String(teil) "12" wurde also das Byte 0x12 (&B0001_0010).

P.S.:
Dadurch spare ich Variablen ein.
Auf die Art könnte man nicht nur Variablen sparen, sondern es würde auch schneller sein - wenn Bascom nicht immer alles über den SRAM laufen lassen würde.
Die Strings und Variablen liegen, wie gesagt, im SRAM.
Der Controller rechnet aber nicht mit SRAM-Registern, sondern mit seinen Rechenregistern. Davon hat er 32 Stück, jedes kann immer ein Byte aufnehmen.
Aus:


CodeBox BascomAVR
Tag = Datum_byte(1) - 0x30

wird also (wahrscheinlich):
  • lade den Inhalt der SRAM-Zelle, auf die Datum_byte(1) zeigt in ein Rechenregister
  • subtrahiere die Konstante von diesem Rechenregister
  • speichere den Inhalt des Rechenregisters ins SRAM, und zwar dahin, wo Tag hinzeigt
danach hatten wir:

CodeBox BascomAVR
Swap Tag

  • lade den Inhalt der, durch Tag referenzierten SRAM-Zelle in ein Rechenregister
  • vertausche die Nibbles dieses Rechenregisters
  • schreibe das Register zurück ins SRAM


CodeBox BascomAVR
Tag = Tag + Datum_byte(2)

  • lade Tag in ein Rechenregister
  • lade Datum_byte(2) in ein anderes Rechenregister
  • addiere das zweite zum ersten
  • schreibe das Ergebnis zurück ins SRAM (genau -> Tag)
Es werden also ständig unnötig irgendwelches Bytes zwischen SRAM und Rechenregistern hin und hergeschaufelt (Bascom optimiert die mMn nicht weg); auch im letzten Schritt.

Man kann das aber selbst einsparen, indem man das einfach als Assembler-Block reinsetzt, ohne unnötiges hin und herschaufeln...
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
da gebe ich dir recht. Aber daran habe ich bisher noch gar nicht gedacht.
ihr habt halt mehr Erfahrung als ich.

Ich will erst mal erreichen, das mein RTC stabil läuft.
Habe gerade eben mal wieder den 01.01.2000 ausgelesen.

aber jetzt erst mal Schönen Abend
 

fredred

Mitglied
1 Okt 2015
76
2
7
Mir geht es in erster Linie darum Chips wie z.B. der DS3213 und damit verbunden die I2C Programmierung verstehen zu lernen.
Ich bin auch über 60 und brauche halt etwas länger, um das alles zu kapieren, und ich will wissen, was ich mache.
Beim Arduino geht ja alles mit Lib's und wehe, es geht nicht.
Das mit dem alter verstehe ich aber das mit Arduino verstehe ich überhaupt nicht. Ich kenne bei dem sehr verbreidetem System das die µC von AVR sind und die meisten Module auch ein ISP bereitstellen. Somit ist ein Zwischenschritt über ein Bootloader auch nicht nötig wenn man sich für Bascom- Pprogrammierung entschieden hat. Nur der verwendete Programmer ist oft ein Problem. Lib’s sind doch „nur Codeschnipsel“ die einen bei der eigenen Programmierung viel abnehmen können. Nicht nur Tippen nein der Lösungsweg ist es.

In diesem Fall geht es mir darum, die Zeit, wenn nötig, aus der Systemzeit des PC's auszulesen, damit ich das nicht immer von Hand einstellen muss.
Da sind wir wieder bei meinem Thema die „ZEIT“. Also du hast die Zeit , wann auch immer, ein PC an dein Projekt anzuschließen um eine genaue Zeit zu synchronisieren okay. Aber das alles benötig mehr Zeit als die Projektzeit sehr genau zu halten. Warum denkst du das dein RTC- Modul( meist mit 32,768 k Quarz bestückt) eine genauere Zeit wie die durch den [/QUOTE]µC erzeugten mit 16,000 M Quarz Oszillator bereit gestellt werden kann. Dein PC erstellt die Uhrzeit auch nur so wie es dein Controller auch macht, wenn erlaubt.
Die PC- Zeit kann natürlich auch nur so genau sein wie die Raumzeit, diese beziehen wir zur Zeit aus dem Web.
Was ich damit sagen möchte. Nicht die Schnelligkeit des Einzelnen ist immer entscheidend nein die Beständigkeit aller.

[/QUOTE]
Mein DS3231 hat sich zwischendurch wieder mehrfach zurückgesetzt, was ich schon in #6 beschrieben habe.
Das Problem besteht also weiterhin.
Ansonsten reicht es mir, in einem Programm die aktuelle Uhrzeit auszulesen, um z.B. einen Datenlogger mit einem Zeit Stempel zu versehen.[
QUOTE]
Woher weist du das es am RTC- Init liegt ?

Bist du dir sicher das es nicht ein Fehler in der Buslinie ist?

Könnte es sein das die Auswertung des µC nicht falsch aber fehlerhaft ist?

Kann es sein du hast keine Zeit dein Projekt Schritt für Schritt zu realisieren ?

Um dein Hauptanliegen zu erfüllen würde ich Vorschlagen teste erst mal den I²C Bus mit nur einen Teilnehmer. LCD- Displays solle erst als letztes im Bus „mitfahren“ dürfen. Die sind so was von faul das Protokoll umzusetzen, das es damit immer wieder Probleme gibt.

Egal was und wie viele Busteilnehmer du anschließen möchtest, mache immer vorab ein Bustest. Mal ein Beispiel hier.
'***********************************
'* hier die minimal Vaiante *
'***********************************
$regfile "m32def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
$baud = 19200

Waitms 100

$lib "i2c_TWI.lib" 'Hardware I²C einbinden
Config Twi = 100000 'Takt 100kHz 400 geht auch noch

' TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !
Twcr = &B00000100 ' nur TWEN setzen

'+++ zum Test ob I²C Hardware OK ist +++
Gosub I2c_test
'++++++++++++++++++++++++++++++++++++++

'für Test die am Port B.0 angeschlossenen Temperatursensoren
Declare Sub Ds1820_alleseriennummern()

'Temperatursensor Anschluß an Portpin B.0
Dim 1wtemp_adresse_1(8) As Byte ' Adresse des Temperatursensors 1
Dim 1wtemp_adresse_2(8) As Byte ' Adresse des Temperatursensors 2
Dim Temp_bytes(9) As Byte
Dim Tempdif As Integer
Dim Tempdif1 As Integer 'Variable zur Temp. Berechnung DeziGrad
Dim Temp1 As Single
Dim Temp2 As Single

'Temperatursensoren DS18S20 + DS18B20 an PortB.0 (Bascom Unterprogramm einbinden)
Config 1wire = Portb.0 'Temperatursensor 1und2
Portb.0 = 1 'Port auf H schalten

'------Temperatursensor erkennen-------
'testet die am Portpin B.0 angeschlossenen Temperatursensoren
Call Ds1820_alleseriennummern()
1wtemp_adresse_1(1) = 1wsearchfirst() 'ist der erste gefundene Sensor
1wtemp_adresse_2(1) = 1wsearchnext() 'suche nächsten
'1wtemp_adresse_3(1) = 1wsearchnext() 'wenn noch mehr erweitern

'Analog-Port aktivieren
Config Adc = Single , Prescaler = Auto , Reference = Internal '= Referenzspannung auf 2.56 Volt
Start Adc
'an Port-Pin A7 LED als Lichtsensor
Dim Hell As Word

'Hinweis: Diese Einstellung reserviert ein paar ROM-Speicher mehr..
'nur nötig wenn eine Var den Typ Single hat. Die letzte Stelle wird gerundet.
'Format für Single eine Nachkommastelle
Config Single = Scientific , Digits = 1 '1 Nachkommastellen oder wie auch immer


'### ist I²C IC für LCD ##################
$lib "Lcd_i2c.lib" 'ersetzt die Standard LCD Library
Dim _lcd_e As Byte 'LCD im 4-Bit Modus betreiben
_lcd_e = 128
Config Lcd = 20 * 4 'Spalten und Zeilen festlegen
' Slaveadressen für Porterweiterung
Const Pcf8574_lcd = &H40 '&B01110000 Dez = 112
Initlcd
'--- Variable für Anzeigeauswahl ---
Dim Lcd_aktualisieren As Byte 'Zähler für LCD-Anzeigen
'Warte bis LCD bereit, falls gleichzeitig Spannung eingeschaltet wird
Waitms 250


'############################################

'##### ist Analog I²C IC ## hiermal in Dez ##
'Const Pcf8591 = 144 'von &H90 &B10010000 AdrPins ist 000
Const Pcf8591 = 158 'bis &H9E &B10011110 AdrPins ist 111
'Variablen für Analog IC
Dim Wadr As Byte
Dim Radr As Byte
Dim I2c_kanal As Byte , I2c_wert As Byte
Dim A0 As Byte
Dim A1 As Byte
Dim A2 As Byte
Dim A3 As Byte
'#############################################

'#### ist Expander I²C IC ## hiermal in Hex ##
Const Pcf8574 = &H7E '&B01111110 Dez = 126 AdrPins ist 111
Const Eingang_schreib_adresse = &B01111110
Const Eingang_lese_adresse = &B01111111
Dim Taste As Byte 'ist Daten Variable Eingang
Dim Alte_tasten As Byte 'ist Merker
' ist Beispiel
'noch ein Expander I²C IC
Const Ausgang_schreib_adresse = &B01111100 '&B01111100 Dez = 125 AdrPins ist 110
Const Ausgang_lese_adresse = &B01111101
Dim Led As Byte 'ist Daten Variable Ausgang(LEDs)
Dim Z As Byte 'Zähler für Testschleife
'#############################################

'##### ist DigPoti I²C IC ####################
Const Ds1803 = &B01011110 '&H9E Dez 158 AdrPins ist 111
'**** Variablen für IC-Poti ****
Dim Poti0 As Byte 'ist Daten Variable Poti0
Dim Poti1 As Byte 'ist Daten Variable Poti1
Dim Potix As Byte 'ist Daten Variable tandem Poti
Dim W0 As Single 'Echtwert
Dim W1 As Single 'Echtwert
'#############################################

'*********************************************************
'* ist eine Test-Sub für Data extern EEprom als Speicher *
'* am I²C Bus ein 24c64 angeschlossen zum speichern *
'* und lesen der Variablen *
'* alle Variablen werden als Strings konvertiert. *
'* somit unabhänig vom Daten-Typ. Auch lange Texte sind *
'* kein Problem mehr. *
'*********************************************************

'---- Eeprom Konstanten festlegen ----
'mehrer unterschiedliche I²C IC am Bus "anzuhängen" ist mit Dev_addr Select kein Problem.
Const Dev_addr_write = &B10100000 'EEPROM Schreibadresse (ST24C64)
Const Dev_addr_read = &B10100001 'EEPROM Leseadresse (ST24C64)
'hier Objekt Einstellungen
Const Stringanz = 6 'String Var Anzahl beginnt mit 0 somit 7 Var
Const Stringmax = 8 'für jedes String 8 Byte reserviert.
Const Speichervoll = 16000 'maximale Speichergröße in Byte (zB.ST24C64)
'############################################

'!!!!!!! Übergabe von Konstanden NICHT ändern !!!!!!!!!!
Const Byteschleife = Stringanz + 1 'bedingt durch String
Const Stringab = Stringmax + 1
Dim Aktschleife As Word
Aktschleife = Stringanz * Stringmax
Aktschleife = Aktschleife + 9 'ist Summe aller Byte + String Endzeichen
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Dim Mem_addr As Word 'Adress Zähler
Dim J As Byte 'Laufvariable für Byte Schleife
Dim Mem_addr_low_byte As Byte At Mem_addr Overlay 'da Eeprom > 8kByte aufteilen
Dim Mem_addr_high_byte As Byte At Mem_addr + 1 Overlay
Dim Aktionen As Word 'Schreib-Zähler
Dim Aktionenl As Word 'Lese-Zähler
Dim S As Byte 'Laufvariable für for-next Schleife schreiben
Dim Number_from_rs(byteschleife) As String * Stringab 'Array der Schreib-Variablen
Dim Four_byte_var_write As String * Stringmax
Dim Byte_var_write(stringmax) As Byte At Four_byte_var_write Overlay ' Elemente Arrayindex
Dim L As Word 'Zyklus fortschreiben lesen 'alle Single_Variablen auslesen
Dim Four_byte_var_read As String * Stringmax
Dim Byte_var_read(stringmax) As Byte At Four_byte_var_read Overlay ' Elemente, Arrayindex

'!!!!! ist nur für Test mit Taster also anpassen !!!!
Config Pinc.3 = Input 'Taster für EEprom schreiben
Portc.3 = 1 'Port auf H schalten
Taster_s Alias Pinc.3 'Taster ein Namen geben

Config Pinc.2 = Input 'Taster für EEprom lesen
Portc.2 = 1 'Port auf H schalten
Taster_l Alias Pinc.2 'Taster ein Namen geben

Config Portc.4 = Output
Eepvoll Alias Portc.4 'LED-Warnung für EEprom voll

'Gosub Lesen 'nach Reset erstmal lesen

'### hier werden die Variablen für Eeprom-Test festgelegt ##########
Dim Datum As String * Stringmax
Dim Zeit As String * Stringmax
Dim Var2 As String * Stringmax
Dim Var3 As String * Stringmax
Dim Var4 As String * Stringmax
Dim Var5 As String * Stringmax
Dim Var6 As String * Stringmax
'(
'+++ Beispiel1 für Single ++++++
Dim Temperatur1 As Single
Temperatur1 = 19.55 'sind 4Byte
Var2 = Str(temperatur1) 'Single als String übergeben
'+++++++++++++++++++++++++++++++

'+++ Beispiel2 für Single ++++++
Dim Temperatur2 As Single
Temperatur2 = -3.55 'sind 4Byte
Var3 = Str(temperatur2) 'Single als String übergeben
'+++++++++++++++++++++++++++++++
')

Lcd_aktualisieren = 255 'ist Startanzeige
Gosub Anzeigen
Wait 4 'nur für Test
Mem_addr = 0 'Sicher ist Sicher

'**** Hauptschleife ****
Do
Waitms 100 'Test Zeit für Terminal-Testanzeige

'Analog Ports lesen
Gosub Analog_dat 'Abfrage Controller AD(Lichtsensor)
Gosub Analog_dat_bus 'Abfrage I2C-Bus AD

'Beispiel: Poti Abfrage
' Gosub Poti_ic_test

'Beispiel: I²C-Bus alle Ports als Eingang
Gosub Eingang

'Beispiel: I²C-Bus alle Ports als Ausgang
' Gosub Ausgang

'Temperatursensoren lesen
Gosub Temperaturmessung 'Abfrage Controller 1wire Bus

'für Eeprom-Test einfach mal so eingefügt
Datum = "01.02.14"
Zeit = "15:10:00"
Var2 = Str(temp1) 'ist Beispiel Temperatursensor1
Var3 = Str(temp2) 'ist Beispiel Temperatursensor2
Var4 = Str(hell) 'ist Beispiel Helligkeit
Var5 = "fredred"
Var6 = "Test-OK"
'(
'für Test Speicher löschen
Datum = ""
Zeit = ""
Var2 = ""
Var3 = ""
Var4 = ""
Var5 = ""
Var6 = ""
')

'!!!alle Variablen für Test mit Hyperterminal anzeigen!!!
Print
Print "lese die Sensoren 1wire an Portb.0 Controller"
Print "Temp1 " ; Var2
Print "Temp2 " ; Var3
Print
Print "lese Lichtsensor von Getadc(7)"
Print "Hell " ; Var4
Print
Print "lese Port-Pins AD I2C "
Print "A0: " ; " Wert ist " ; A0
Print "A1: " ; " Wert ist " ; A1
Print "A2: " ; " Wert ist " ; A2
Print "A3: " ; " Wert ist " ; A3
Print
Print "lese alle 8 Portpin's Expander"
Print "Taste 1 = " ; Taste.0
Print "Taste 2 = " ; Taste.1
Print "Taste 3 = " ; Taste.2
Print "Taste 4 = " ; Taste.3
Print "Taste 5 = " ; Taste.4
Print "Taste 6 = " ; Taste.5
Print "Taste 7 = " ; Taste.6
Print "Taste 8 = " ; Taste.7
Print
'Print "lese DigPoti" 'wird in Sub durchgeführt da für Test eine Schleife eingebaut.
'Print "Volt-P0 = " ; W0
'Print "Volt-P1 = " ; W1
'Print


'!!! ausgewählte Daten in Eeprom schreiben oder lesen !!!
'Aktionen mit Taster in Echt durch Ereignis ersetzen zB. Timer
Debounce Taster_s , 0 , Schreiben , Sub 'Taster entprellen
Debounce Taster_l , 0 , Lesen , Sub

'(
'--- hier zum Daten schrieben --------
If Taster_s = 0 Then 'wenn Taste gedrückt schreiben
Waitms 100 'nur für Test
Gosub Schreiben
End If
'--- hier zum Daten lesen ------------
If Taster_l = 0 Then 'wenn Taste gedrückt lesen
Waitms 100 'nur für Test
Gosub Lesen
End If
')


Loop
'**** END Hauptsschleife ****


'### BEGINN in ext EEPROM schreiben (byte write method) ###
Schreiben:

Config Base = 0 'Zähler mit 0 beginnen ist wichtig für lesen
'--- für Test ---
Print "Byte der Var-Variablen schreiben " ; "Aktionen " ; Aktionen
Print
'----------------

Mem_addr = Aktionen * Aktschleife 'step Aktionen

'LED Anzeige wenn Eeprom gelesen werden sollte
If Mem_addr >= 113 Then Eepvoll = 1 '113 ist nur ein Beispiel kann auch [Speichervol- xxx] sein

For S = 0 To Stringanz 'for-next mit 0 beginnen da Base = 0
If S = 0 Then Number_from_rs(0) = Datum
If S = 1 Then Number_from_rs(1) = Zeit
If S = 2 Then Number_from_rs(2) = Var2
If S = 3 Then Number_from_rs(3) = Var3
If S = 4 Then Number_from_rs(4) = Var4
If S = 5 Then Number_from_rs(5) = Var5
If S = 6 Then Number_from_rs(6) = Var6

Four_byte_var_write = Number_from_rs(s) 'String Variable S schreiben

For J = 0 To Byteschleife 'Laufschleife schreiben
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Schreibadresse
I2cwbyte Byte_var_write(j) 'Sendet Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Schreibadresse mit jedem Schleifendurchlauf erhöhen
Waitms 10 'Warten auf ext. EEPROM Rückmeldung
'--- nur für Test ---
Print "Var-Variable " ; S ; " = Adresse " ; Mem_addr ; " Bytewert " ; Byte_var_write(j)
'--------------------
Next J
'--- nur für Test ---
Print "!! Ausgabe !! " ; Four_byte_var_write
Print
'---------------------
Next S

'ist Speicher am Ende dann wieder von vorn
If Mem_addr = Speichervoll Then
'schreiben beginnt wieder ab Adr 0. Rest bleib erhalten.
Aktionen = 0
End If
Incr Aktionen 'nächsten Schreibzyklus anstoßen
Config Base = 1 'Wichtig: Schleifenzähler wieder auf 1 setzen
Return
'### ENDE ext EEPROM schreiben ###


'-----------------------------------------------------------

'### BEGINN aus ext.EEPROM lesen ###
Lesen:

'Zähler mit 0 beginnen da este Zelle 0 ist. Ansonsten wird lesen beendet wenn Inhalt leer.
'siehe Abfrage "wenn -NAN"
Config Base = 0
Mem_addr = 0 'da Variable auch für schreiben gesetz ist zum lesen zurück setzen.
Aktionenl = 0 'starte Lesung bei Adr 0

For Mem_addr = Aktionenl To Speichervoll 'ist max Byte für Eeprom
'--- nur für Test ---
'Print "Byte der 6 Var-Variablen lesen " ; "Zyklus " ; Aktionenl
'Print
'--------------------
For L = 0 To Stringanz

For J = 0 To Byteschleife 'Laufschleife lesen
I2cstart
I2cwbyte Dev_addr_write 'Sendet ext. EEPROM Adresse zum Schreiben
I2cwbyte Mem_addr_high_byte 'Sendet Speicher-Leseadresse
I2cwbyte Mem_addr_low_byte 'Sendet Speicher-Leseadresse
Waitms 10
I2cstart 'zweites Start ohne vorheriges Stop (siehe Datenblatt "random address read")
I2cwbyte Dev_addr_read 'Sendet ext. EEPROM Adresse zum Lesen
I2crbyte Byte_var_read(j) , Nack 'Liest Datenbyte
I2cstop
Mem_addr = Mem_addr + 1 'Leseadresse mit jedem Schleifendurchlauf erhöhen

'--- nur für Test ---
' Print "Var_Variable " ; L ; " = Byte " ; Mem_addr ; " Bytewert " ; Byte_var_read(j)
'--------------------
'wenn -NAN dann Auslesung beenden(soll nicht unbeschriebenen Speicher lesen)
If Four_byte_var_read = "" Or Byte_var_read(j) = 255 Then
Print Mem_addr ; " Byte gelesen "
Eepvoll = 0 'LED aus
Return
End If
Next J

'### BEGINN Terminal_log Ausgabe für Auswertungen in Excel ###
'### CSV Trenzeichen ist [;] ###
Print Four_byte_var_read ; ";" ;
'Daten wurden gelesen
Eepvoll = 0 'LED aus

'Nach Zwischenauslesung Speicherbereich fortsschreiben soll ja nicht
'immer die gleichen Zellen beschreiben("Lebensdauer")
If Mem_addr = Speichervoll Then
'schreiben beginnt wieder ab Adr 0. Rest bleib erhalten.
Aktionen = 0
End If
Next L
Print Chr(3) 'wird benötigt für CSV(End Off Text nach Zyklus)
Incr Aktionenl 'Lesezyklus hochzählen bis -Nan
Next Mem_addr
Config Base = 1 'Wichtig:Schleifenzähler wieder auf 1 setzen
Return
'#### ENDE ext.EEPROM lesen ####


'-----------------------------------------------------
I2c_test:

Dim Chipaddress As Byte
Dim Anzahl As Byte

'I²C Porterweiterung testen
'Alle Adresen suche und Anzeigen
'Step 2 soll nur IC Addresse aufrufen "hast dich gemeldet"
Print "I2C Scan start"
For Chipaddress = 0 To 254 Step 2 ' IC's am I²C-Bus erkennen
I2cstart 'send start
I2cwbyte Chipaddress 'sende Adresse auf Bus
If Err = 0 Then 'Chip gefunden
Incr Anzahl
'nur für Test
'Print "Hex-Adr " ; Hex(chipaddress)
'Waitms 500
'da Adressen bekannt in Anwendung in Klartext anzeigen
If Chipaddress = Pcf8574_lcd Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein PCF 8574P Adr 000 für LCD" 'LCD 4x20 am Bus
Print
End If

If Chipaddress = Dev_addr_write Then 'ist &B10100000 EEPROM Schreibadresse (ST24C64)
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein ST24C64 Adr 000"
Print
End If

If Chipaddress = Pcf8591 Then 'ist &B10011110 Analog Schreibadresse (PCF8591)
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein PCF 8591 Adr 111"
Print
End If

If Chipaddress = Pcf8574 Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein PCF8574AP Adr 111"
Print
End If

If Chipaddress = Ds1803 Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein DS1803 Adr 111"
Print
End If

'hier können noch weitere I²C IC Teilnehmer abgefragt werden.
'(
Print
If Chipaddress = xxx Then
Print "gefunden " ; "h " ; Hex(chipaddress) ; " b " ; Bin(chipaddress)
Print "ist ein ICxxx Adr xxx"
Print
End If
')

End If
'zählt Teilnehmer
Next
Print "am I2C " ; Anzahl ; " Bus-Teilnehmer gefunden "
Return

'-------------------------------------------------------------------------------

'############# nach Neustart Temperatursensor Test ###############

'wird dieser Test Erfolgreich beendet wird die "Messung" oben in den Variablen
'geschrieben [1wtemp_adresse_1(1)] ist der erste Sensor und
'und [1wtemp_adresse_2(1)] ist der zweite usw.

'Gibt die Seriennummer aller Sensoren des Bus aus.
'wenn Hardware-Fehler wird dieser angezeigt.

Sub Ds1820_alleseriennummern()
Local Crc As Byte
Local I As Integer
Local Anzahl As Integer
Dim Adresse(8) As Byte
Adresse(1) = 1wsearchfirst() 'prüft den ersten Teilnehmer am Bus
If Err = 0 Then 'Wenn err, dann gibt es keinen Sensor

'********************************************************
'* [DS18x20] DS18S20 ist ein 9 Bit Family Adr &H10 *
'* und DSB20 ein 12 Bit Family Adr &H28 *
'* somit große Unterschiede bei der "Empfindlichkeit" *
'* Das lesen der Bit's ist somit auch Unterschiedlich. *
'********************************************************

'!! meine Erfahrungen zeigen. an ein Pin-Port sollten !!
'!! immer die gleichen Family IC "hängen" !!

'ist nur für Info die Hex-Adresse ist "Name" mit dieser Kenntnis
'kannst Du mit [1wwrite &H55 und 1wwrite Sensor1_id("Name") , 8
'jeden einzeln ansprechen. Mach bei mehreren Sensoren Sinn.
Print
Print "Sensoren an Port B.0 prüfen"
Print "sind Hex-Adresse der DS18x20"

'ab hier prüfen
Do
Crc = Crc8(adresse(1) , 7)
If Crc <> Adresse(8) Then Print "Daten fehlerhaft gelesen (CRC-Fehler)!"
For I = 1 To 8
Print Hex(adresse(i)) ;
Print " ";
Next
Print

Adresse(1) = 1wsearchnext() 'nächste suchen
Loop Until Err = 1
End If
Anzahl = 1wirecount() 'Anzahl der Sensoren
Print "Anzahl der Sensoren am Bus: " ; Anzahl
If Anzahl = 0 Then Print "kein Sensor gefunden"
Print
Print "Test abgeschlossen"
Print "Hauptprogramm wird gestartet"
Print
Wait 5
End Sub


'----------------------------------------------
Temperaturmessung:

'bei allen Sensoren den Messvorgang starten
1wreset
1wwrite &HCC ' SKIP ROM, alle Sensoren ansprechen
1wwrite &H44 ' CONVERT T, Temperatur messen
'Zeit geben
Waitms 100

'===== erster Temp.-Sensor ist ein S Typ=====
1wreset
1wverify 1wtemp_adresse_1(1)
1wwrite &HBE ' Read Scratchpad, Temperatur auslesen
'Zeit geben
Waitms 100
Temp_bytes(1) = 1wread(8)
Tempdif = Makeint(temp_bytes(1) , Temp_bytes(2)) 'erstes und 2 Byte(LSB+MSB) zusammenfügen
Tempdif = Tempdif * 50
Tempdif = Tempdif - 25.5
Tempdif1 = Temp_bytes(8) - Temp_bytes(7)
Tempdif1 = Tempdif1 * 100
Tempdif1 = Tempdif1 / Temp_bytes(8)
Tempdif = Tempdif + Tempdif1
Temp1 = Tempdif / 100
Var2 = Str(temp1)
Waitms 10
'(
'===== zweiter Temp.-Sensor wenn auch ein S Typ =====
' Anfrage senden
1wreset
1wverify 1wtemp_adresse_2(1)
1wwrite &HBE ' Read Scratchpad, Temperatur auslesen
'Zeit geben
Waitms 10
Temp_bytes(1) = 1wread(8)
Tempdif = Makeint(temp_bytes(1) , Temp_bytes(2)) 'erstes und 2 Byte(LSB+MSB) zusammenfügen.
Tempdif = Tempdif * 50
Tempdif = Tempdif - 25.5
Tempdif1 = Temp_bytes(8) - Temp_bytes(7)
Tempdif1 = Tempdif1 * 100
Tempdif1 = Tempdif1 / Temp_bytes(8)
Tempdif = Tempdif + Tempdif1
Temp2 = Tempdif / 100
'Zeit zum Messen geben
Waitms 10
')

'===== erster Temp.-Sensor wenn es ein B Typ ist =====
' Anfrage senden
1wreset
1wverify 1wtemp_adresse_2(1)
1wwrite &HBE ' Read Scratchpad, Temperatur auslesen
'Zeit geben
Waitms 100
Temp_bytes(1) = 1wread(9)
Tempdif = Makeint(temp_bytes(1) , Temp_bytes(2)) 'erstes und 2 Byte(LSB+MSB) zusammenfügen.
Tempdif = Tempdif / 8 'hier der Unterschied
Tempdif = Tempdif * 50
Tempdif = Tempdif - 25
Tempdif1 = Temp_bytes(8) - Temp_bytes(7)
Tempdif1 = Tempdif1 * 100
Tempdif1 = Tempdif1 / Temp_bytes(8)
Tempdif = Tempdif + Tempdif1
Temp2 = Tempdif / 100 'hier der Unterschied
Var3 = Str(temp2)
' Waitms 10

Lcd_aktualisieren = 253 'ist Startanzeige
Gosub Anzeigen


Return
'------------------------------------------------------

Analog_dat:
'Helligkeit lesen
'4 LEDs(5mm) parallel und 10n Kontensator Kathode an GND Anode an Pin
Hell = Getadc(7)
Gosub Anzeigen 'Sensor(LED) an Port-Pin A7
Return


'------------------------------------------------------
'I²C Analog IC = Pcf 8591 Adr-Pin alle H = 111
'Binär für besseres Verständnis. Kann auch in Hex oder Dez angegeben werden.
'oder I2c_Kanal als For-Next Schleife.
Analog_dat_bus:

Wadr = &B10011110 ' Schreibadresse für 8591
Radr = &B10011111 ' Leseadresse

I2c_kanal = &B00000001 'Port-Pin selektieren
Gosub Geti2cadc 'Wert holen
A0 = I2c_wert 'Wert in Variable schreiben

I2c_kanal = &B00000010
Gosub Geti2cadc
A1 = I2c_wert

I2c_kanal = &B00000011
Gosub Geti2cadc
A2 = I2c_wert

I2c_kanal = &B00000100
Gosub Geti2cadc
A3 = I2c_wert

'Sub in Sub spart einige RAM speicher
Geti2cadc: 'Werte abholen
I2cstart
I2cwbyte Wadr 'Schreibadresse senden
I2cwbyte I2c_kanal
I2cwbyte 0 ' Null auf D/A-Wandler
I2cstop

Waitms 10

I2cstart ' Start 'Leseadresse übermitteln
I2cwbyte Radr
I2crbyte I2c_wert , 9 'Wert lesen
I2cstop
Return
'------- End Analog Abfrage ----------------------

'******ist die Poti-Demo wird gestartet wenn Oben akteviert *********
' zum Kennenlernen wie die 2 Potis angesprochen werden.

'----SUB Bus IC-Poti Adr = b01011110 alle Adr Pins auf H
Poti_ic_test:
Lcd_aktualisieren = 254 'Anzeige Flag setzen
Print "erstes Poti hochregeln"
For Poti0 = 0 To 255 'Poti0 = Zähler. Später durch Ereignis ersetzen
I2cstart
I2cwbyte &B01011110 'control-byte
I2cwbyte &B10101001 'ist Poti0
I2cwbyte Poti0 'Byte-Wert schreiben
I2cstop 'Bus frei geben
'ab hier Umrechnung in Volt
W0 = 0.018 * Poti0 'abgleichen
Print "Volt-P0 = " ; W0
Gosub Anzeigen 'Anzeige Flag wird vor Start der Sub gesetzt
Next

Print "zweites Poti hochregeln"
For Poti1 = 0 To 255 'Poti1 = Zähler. Später durch Ereignis ersetzen
I2cstart
I2cwbyte &B01011110 'control-byte
'hier kommt der Unterschied
I2cwbyte &B10101010 'ist Poti1
I2cwbyte Poti1 'Byte-Wert schreiben
I2cstop
'ab hier Umrechnung in Volt
W1 = 0.018 * Poti1 'abgleichen
Print "Volt-P1 = " ; W1 'Nur Test
Gosub Anzeigen 'aktuallisieren
Next


'beide Potis gleichzeitig abregeln
Print "beide Potis gleichzeitig abregeln" 'Nur Test
For Potix = 255 To 0 Step -1 'Potix = Zähler. Später durch Ereignis ersetzen
I2cstart
I2cwbyte &B01011110 'control-byte
'hier kommt der Unterschied
I2cwbyte &B10101111 'Potix = Poti0 und Poti1= Tandempoti
I2cwbyte Potix 'zu schreibende Werte
I2cstop
W0 = 0.018 * Potix 'Nur Test
W1 = 0.018 * Potix
Print "Poti0 " ; W0 ;
Print " Poti1 " ; W1
Gosub Anzeigen 'aktuallisieren
Next

Return
'**********Ende Demo****************************

'---Beispiel alle Ports für IC2 als Eingänge ---------
Eingang:

I2cstart
I2cwbyte Eingang_schreib_adresse
I2cwbyte &B11111111 'alle Ports als Eingang. geschalten wird mit GND
I2cstop

I2cstart
I2cwbyte Eingang_lese_adresse
I2crbyte Taste , Nack 'Taste lesen

'Print Bin(taste) 'nur für Test

I2cstop
Waitms 100

Return

'---Beispiel alle Ports für IC2 als Ausgänge -------
Ausgang:

I2cstart
I2cwbyte Ausgang_schreib_adresse
'I2cwbyte &B00000000 'alle Ports als Ausgang gegen Vcc
I2cwbyte &B11111111
I2cstop

'nur für Test
Led.z = 0 'sind alle Portpins
For Z = 0 To 7
I2cstart
I2cwbyte Ausgang_schreib_adresse
I2cwbyte Led.z
Print "LED-An " ; Z ; " " ; Led.z
I2cwbyte Led.z
Print "LED-Aus " ; Z ; " " ; Led.z
Waitms 100 'warte 100 Millisekunden
Next

'alle LED's abschalten
I2cwbyte Ausgang_schreib_adresse
Led = 1
I2cwbyte Led
Print Led
Wait 1 'warte 1Sekunde
I2cstop
Return


'************ Bereich für LCD -Anzeigen *4x20 ********
Anzeigen:
'Cls 'wenn gewünscht lösche alten Inhalt
'****** Startfenster *******
If Lcd_aktualisieren = 255 Then
Print "Startanzeige"
Locate 1 , 1 'Cursor auf 1 Zeile, 1 Spalte
Lcd " Hallo LCD ist OK "
Locate 2 , 1 'Cursor auf 2 Zeile, 1 Spalte
Lcd " Hauptprogramm wird "
Locate 3 , 1 'Cursor auf 3 Zeile, 1 Spalte
Lcd " gestartet "
Locate 4 , 1 'Cursor auf 4 Zeile, 1 Spalte
Lcd " Bitte warten "
End If

'***************************

'hier zur LCD - Anzeige für Poti
If Lcd_aktualisieren = 254 Then
Locate 1 , 1 'Cursor auf 1 Zeile, 1 Spalte
Lcd " Poti Anzeige "
Locate 2 , 2 'Cursor auf 2 Zeile, 2 Spalte
Lcd " *Werte in Volt* "
Locate 3 , 2 'Cursor auf 3 Zeile, 2 Spalte
Lcd " Poti0 = " ; W0 ; " "
Locate 4 , 2 'Cursor auf 4 Zeile, 2 Spalte
Lcd " Poti1 = " ; W1 ; " "

Waitms 500 'nur für Test
End If


'hier zur LCD - Anzeige für Temperatursensoren
If Lcd_aktualisieren = 253 Then
Locate 1 , 1 'Cursor auf 1 Zeile, 1 Spalte
Lcd " Sensoren lesen "
Locate 2 , 1 'Cursor auf 2 Zeile, 1 Spalte
Lcd " Licht " ; Hell ; " "
Locate 3 , 1 'Cursor auf 3 Zeile, 1 Spalte
Lcd " Temp1: " ; Var2 ; " ßC "
Locate 4 , 1 'Cursor auf 4 Zeile, 1 Spalte
Lcd " Temp2: " ; Var3 ; " ßC " 'Zeichen[ß] ist bei verwendeten LCD Gradsymbol
End If
'***************************



'hier weitere Anzeige Modi (zur Zeit 3 von 255 )
'If Lcd_aktualisieren = 252 Then 'und so weiter

'einfach eine Lcd_aktualisieren x hier rein kopieren und anpassen.
' End If


Return

Dann betrachte in aller Ruhe jeden einzeln Schritt. Wenn dich nun noch etwas unverständlich ist, dann beschreibe es so genau wie möglich und du wirst eine Lösung bekommen. Kann natürlich auch so eine ehrliche sein wie meine „So geht es nicht wenn die Zeit nicht als Raumzeit betrachtet wird“ oder natürlich auch so eine „mach aus dem Komma ein Punkt“.Verschweigen oder wissen meist selber nicht wann dies ersetzen „Sinn“ macht

Mit freundlichen Grüßen fredred
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Guten Abend fredred,

Das ist ne "Menge Holz", muss ich erst mal verdauen. Vielen Dank für Deine Mühe.
Ich muss aber ein paar Anmerkungen loswerden.

- Das mit dem Arduino ist mir schon klar. Blos nach meiner Ansicht wird da sehr viel mit Libs gearbeitet. Es mag zwar schneller zu einem Ziel führen, aber ich finde das hardwarenahe Bascom persönlich lehrreicher.

Habe mir mal ein Mega2560 Board zugelegt und ein TFT Touchscreen dazu (beides von ELEGO).
Z.Z läuft das Display nur mit den Libs von ELEGO, auch da will ich mich aber noch einarbeiten, um einfach auch mal die Arduino Programmierung näher kennen zu lernen.
Was mich jetzt schon stört, das man sehr auf Semis und Klammern achten muss, das nervt mich persönlich einfach.


- als ich den RTC bekommen habe, war das erste, dass ich den I2C Test durchgeführt habe, dabei wurden auch alle angeschlossenen Teile erkannt.
Heute hat er übrigens ohne Probleme gestartet, als ich mein Board eingeschaltet habe.
Kann es sein, wenn ich ein Programm flashe, das dabei unsinnige Daten über SDA und SCL geschickt werden. Denn auch mein LCD spinnt häufig nach dem Flashen und Neustart eines Programms. (sehe weiter unten)

Das man mit Bordmitteln der AVR's genauere Zeiten erzeugen kann, ist mir auch klar. Ich habe z.Z. auch kein spezielles Projekt, wo ich die RTC einsetzen will.
Mir geht es vor allem um "Learning by doing", also Erfahrung sammeln mit den Chips.

Die Routinen vom LCD werde ich mir auch mal genauer ansehen, wie gesagt meins spinnt öfter.
(LCD 2004A v2.0 über Portexpander PCF8574AT an der I2C), das sagt dir sicher was.

So das soll es für heute gewesen sein.
Also nochmals Danke für deine Hilfe und auch die der anderen.
werde weiter testen.

viele Grüße DS1074
 

fredred

Mitglied
1 Okt 2015
76
2
7
Hallo,
ich weis das ich viel Mist schreibe aber der Hauptgrund für Antwort war
- Das mit dem Arduino ist mir schon klar. Blos nach meiner Ansicht wird da sehr viel mit Libs gearbeitet. Es mag zwar schneller zu einem Ziel führen, aber ich finde das hardwarenahe Bascom persönlich lehrreicher.
Aber du bestehst weiter darauf dies Module mit C zu programmieren. Warum??? Beispiele und Lib’s gibt es für Bascom auch sehr viele.
In letzter Zeit nutze ich auch nur noch die Module die als Arduino sehr preiswert angeboten werden. Kann den Lötkolben auch nicht mehr so genau führen und die fertigen Dinger sind noch billiger als die Einzelteile.
Beispiel für mittlere Aufgaben. Gleich mit Bedienteil sieht grob so aus und kostet nicht mal 5 € Standartdisplay 16x2:
1579092837980.png
Die Tasterabfrage wird mit ADC also auch nur mit ein Kabel zum Controller realisiert.
und ein ATmega328p Micro Controller ca.4 €
1579093063798.png
Hab natürlich auch Mega2560 Board und TFT Touchscreen Projekte mit Bascom- Code im Einsatz. Die Module haben alle eine ISP- Schnittstelle dafür bietet Bascom doch viele Treiber für Programmer an. Ich nutze zur Zeit den USBASP beim netten Chinamann ca. 3€ mit USB-Kabel. Sind sehr zuverlässig, wie es halt mit USB ist.
1579093371018.png

Muss doch noch mal was allgemeines verklickern.

Zitat von DS1074 „ich finde das hardwarenahe Bascom persönlich lehrreicher..“
Das ist natürlich Falsch. Bin der Meinung unter allen Hochsprachen ist wohl Bascom am weitesten entfernt von der µC-Hardware und auf keinen Fall lehrreicher die Controller zu verstehen. Das erklärt LotadaC immer sehr gut ohne eine Sprache zu bevorzugen.
Um den Programmablauf allgemeinverständlich zu erstellen ist (Basic) unschlagbar. Bascom erlaubt sehr einfach an fast jeder Programmstelle Assemblerbefehle einzufügen, wenn man gezwungen wird, sehr nah an die Hardware zu kommen. Somit ist dann der verbreitete Nachteil unbegründet.
Ich mag Bascom auch aber aus anderen Grund. Ich habe bzw. nehme mir die Zeit mehrere Wege zum Ziel zu suchen.
Sind die kleinen Umwege gut beschrieben bin ich nicht der Erste am Ziel aber viele kommen nach. Denn die Wanderkarte ist leicht zu lesen und mancheiner finde dadurch einen optimalen oder kürzeren Weg.
Nach meiner Meinung ist es der Grund warum auch in der Industrie C/C++ bevorzugt wird.
Der kürzeste Weg soll schnell gefunden werden(Zeit ist Geld) und die Wanderkarte soll nicht so einfach für jedermann lesbar sein.

Bitte an alle:
Betrachtet die obigen Schriftzeichen als Gedankenspielereien aber niemals als thematische oder fachliche Abhandlung.
Danke der Spinner Fredred
P.S. Versuche keine Kommentare mehr zu schreiben aber wenn solche Fragen kommen, kann ich mich einfach nicht bremsen. Ich habe vieles vergessen aber nicht wie ich mal angefangen habe wo es noch kein Forum gab um nachzufragen und die Literatur unerschwinglich war. Von der Hardware ganz zu schweigen(ein IC D100 für 3 D Mark zu bekommen war ein Schnäppchen
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Hallo fredred,
ich möchte hier keine Grundsatzdiskussion starten.
ich habe mir vor der Wende meine ersten Kenntnisse in Assembler (Z-1030 DDR Computer mit U880) angeeignet, dann kamen die ersten Basic Interpreter auf.

Nach der Wende hatte ich die Möglichkeit, auf die AVR' s zuzugreifen. Daraufhin habe ich mit Bascom angefangen. weil es am Anfang für mich einfacher war, als die Chips komplett in Maschinensprache zu programmieren. Deshalb meine persönliche Neigung zu Bascom, weil ich es auch, wie du geschrieben hast, allgemeinverständlicher finde. (Die Betonung auf persönlich ist beabsichtigt)

Ich habe z.B. für eine DMX Licht-Steuerung das Grundprogramm in Basic und die zeitkritischen Programmteile darin in Assembler geschrieben.

Ich bin beruflich kein Programmierer, sondern habe mir das Wissen in meiner Freizeit selbst angeeignet.

Aus reinem Interesse habe ich mir erst letztes Jahr kurz vor Weihnachten den Atmega2560 mit einem Grafik TFT LCD zugelegt,
weil ich halt auch dies mal testen will.
Das hat mit meinem 4*20 Text-LCD Display nichts zu tun, das ist am Pollin Board angeschlossen, und spinnt halt immer noch.
Ich habe mich diesbezüglich vielleicht falsch ausgedrückt.

Nur wollte ich mir den Mega2560 nicht gleich bei den ersten Versuchen mit ISP Flashen "verfusen".
Danke für den Hinweis auf den Programmer,
Ich habe mir deshalb noch ein kleines UNO R3 Modul bestellt, woran ich Versuche in Bascom durchführen will.

Ich bestehe also auf keiner Hochsprache.
Ich bin einfach aufgeschlossen für Neues, solange ich es verstehe. Befasse mich nebenbei auch mit in Python.

Ich hoffe, das ich einige Unklarheiten beseitigen konnte, werde ansonsten erst mal deine Programmdatei analysieren, in der Hoffnung, das ich die Fehler bei meinen Geräten noch herausfinde.

Zwei Fragen habe ich noch:
1. zur Bedienung des Forums.
Wie füge ich eine oder mehrere Zeilen als Zitat ein. (also nicht den ganzen Text eines anderen Verfassers?)

2. zur Bascom IDE:
Kann man erreichen, das Kommentare untereinander stehen und nicht je nach Länge der Befehle davor versetzt?

Danke im Voraus
MfG DS1074
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.299
146
63
Mittelhessen, Giessen
Sprachen
ANSI C, C++, C#, Java, Kotlin, Pascal, Assembler, PHP
Wie füge ich eine oder mehrere Zeilen als Zitat ein. (also nicht den ganzen Text eines anderen Verfassers?)
Textbereich mit linker Maustaste markieren, mit der Maus drüber. Dann ...
Multizitat wählen, um mehrere Textbereiche auch von anderen Beiträgen in dem Thema zu sammeln und später einzufügen. Einfügen mit Button "Zitate einfügen".
Zitieren wählen, um den Textbereich sofort einzufügen.

Dirk :ciao:
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Hallo LotadaC,

in #27 hast Du mir diesen Tipp gesendet
habe ich heute getestet:

Code:
@echo off
for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%%A
echo %time% %date% %daynumber%
dabei kam folgende Fehlermeldung von der cmd:

Microsoft Windows [Version 10.0.18362.535]
(c) 2019 Microsoft Corporation. Alle Rechte vorbehalten.
C:\Users\Office>@echo off
for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Form
at:csv') do set daynumber=%%A
"%%A" kann syntaktisch an dieser Stelle nicht verarbeitet werden.
echo %time% %date% %daynumber%

damit kann ich aber nichts anfangen, DOS ist nicht meine Stärke.

Vielleicht kennst du dich damit aus und kannst mir weiterhelfen.
Gruß DS1074
 
Zuletzt bearbeitet:

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Bascom erlaubt sehr einfach an fast jeder Programmstelle Assemblerbefehle einzufügen, wenn man gezwungen wird, sehr nah an die Hardware zu kommen.
Oder wenn man das selbst will. Außerdem kannst Du da auch sehr schön auf Bascom-Variablen zugreifen (also die SRAM-Adressen verwenden)


CodeBox BascomAVR
Dim B As Byte
'irgendwelcher Code
$ASM
Lds R16, {B} 'läd "Byte B" aus dem SRAM nach R16
$end ASM

In Bascom (gilt sicher auch für viele andere Hochsprachen) kannst Du halt mal quickNdirty irgend'n Zweizeiler hinknallen, der irgendein Problem löst - wo in ASM mehrere Seiten Code nötig werden würden. Daß der resultierende Maschienencode da deutlich länger sein kann und/oder das Programm alles andere als effizient, steht auf 'nem anderen Blatt. Mach ich ja auch so. Meine Meinung ist aber, daß man dann versuchen sollte zu verstehen, was der Controller aus dieser oder jener Hochsprachen-Instruktion machen könnte, und das bereits beim Lösungsweg beachtet.
2. zur Bascom IDE:
Kann man erreichen, das Kommentare untereinander stehen und nicht je nach Länge der Befehle davor versetzt?
Eigentlich sollte es so sein:
Steht in einer Zeile vor dem Kommentar nichts weiter (also kein Befehl etc...), bleibt der Kommentar da, wo Du ihn hingesetzt hast.
Steht da was, wird der Kommentar an eine festgelegte Position platziert. Wo festgelegt?
Hauptmenu -> Optionen -> Umgebung -> Comment Position (Standard ist Spalte 60)

Sollte - aus irgendeinem Grund ist diese Linie alles andere als gerade...

habe ich heute getestet:

dabei kam folgende Fehlermeldung aus der cmd:
nicht als reines Kommando, sondern in einer Batch-Datei
(Also Du erstellst irgendwo irgend'ne Textdatei, kopierst da den "Code" rein, speicherst die ab und tauscht hinterher die Extension von .txt auf .bat
diese Datei kannst Du dann entweder in der Eingabeaufforderung bzw als CMD durch Eingabe des Namens (und ggf des Pfades) starten, oder wie jede andere ausführbare Datei auch im Windows Dateiexplorer (Doppelklick etc...))
Wenn Du das ganze nicht aus der Eingabeaufforderung heraus startest, wird das Fenster sofort nach der Ausgabe geschlossen; um das zu verhindern einfach als letzte Zeile ein pause eingeben...
Code:
@echo off
for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%%A
echo %time% %date% %daynumber%
pause
Um die Datei später zu bearbeiten: rechtsklick ->bearbeiten
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Wie gesagt, Assembler aus Basic habe ich schon verstanden und auch selbst schon angewendet.

Die Batch Datei habe ich, wie du beschrieben hast, erzeugt und sowohl direkt aufgerufen, bzw. als Kopie in der cmd gestartet.
Beides mit o.g. Fehlermeldung (nur die 'pause' hatte ich nicht mehr im Hinterkopf, ist ja auch so einfach, wenn man's weiß)
Werde morgen alles nochmal ausprobieren, aber was bedeutet 'daynumber=%%A'? Damit kenne ich mich halt nicht so aus und das wurde ja moniert.

Und das mit den Kommentareinrückungen ist also nicht nur mir aufgefallen, oder?

Bis morgen
Gruß DS1074
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Wenn Du das direkt in die Eingabeaufforderung eingeben willst, mußt Du statt der doppelten "%" einfache nehmen, also

Code:
for /F "skip=2 tokens=2-4 delims=," %A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%A
echo %time% %date% %daynumber%
(Echo abschalten und Pause machen hier keinen Sinn)
Genauso sollte auch folgendes gehen:
Code:
for /f %A in ('wmic path win32_localtime get dayofweek^|findstr /v /r "^$"') do (set daynumber=%A)
echo %time% %date% %daynumber%
 

ds1074

Neues Mitglied
7 Jan 2020
29
0
1
Sprachen
BascomAVR, Assembler, Python
Danke für den Tipp, es funktioniert erst mal.
da wäre ich selbst nicht draufgekommen. Wo findet man diese Infos, würde mich auch interessieren.

Nur ab und zu wird vor dem "%time% %date% %daynumber%" String noch ein 0x0A geschickt. Muss ich vor dem Empfang den UART leeren, und wenn ja, wie?
Sonst verschiebt sich natürlich der ganze String und in der Berechnung für die RTC Uhr wird Unsinn erzeugt.

Grüße DS1074
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Wo findet man diese Infos, würde mich auch interessieren.
Mit der Suchmaschine Deiner Wahl. Knackpunkt sind - wie immer - die Suchbegriffe. Ich hatte "Wochentag" und "Batch" gewählt...
Nur ab und zu wird vor dem "%time% %date% %daynumber%" String noch ein 0x0A geschickt.
0x0A wäre ein Carriage Return - hmm … keine Ahnung...
Wie empfängst Du die Daten im Controller? mit Input? (Da wäre das CR ja der Default "serial input line Terminator").

Standardmäßig würde Input übrigens selbst das Senden eines CR nach jedem Empfang auslösen (wäre ja die Gegenrichtung - ich hatte aber auch schon mal irgendwo sporadisches Übersprechen von Tx auf Rx…). Das kannst Du an drei verschiedenen Stellen unterbinden. Schau mal Input, Config Input und Echo

(Hmm… Bascom legt die Information Echo/Noecho in Bit3 von R6 ab? Also man könnte das Echo auch mit SBR/CBR an/abschalten?? -> Memo an mich selbst: irgendwann mal ausprobieren.)

P.S.: hast Du mal geschaut (Simulator), ob nebenbei auch der UART-Transmitter aktiviert wird? Wegen Input wird ja irgendwann mal RXEN gesetzt; setzt Bascom da auch TXEN mit?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)