• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

Fragen zur Software

upigors

Geowizard
ich hab auch noch einen:
warum funktioniert dieser eigentlich sehr simple Code nicht? Ziel ist es 4 Eingänge A.0 - A.3 nacheinander abzufragen um dann an 2 Ausgängen was passieren zu lassen. Sicher nicht elegant gelöst (diese Idee fiel mir aber mal grad ein) aber so rein prinzipiell versteh ich nicht warum bereits nach erfülltem A.0 (auf GRD gelegt) das Programm nach D: springt und die doofe LED leuchtet :???:
Ich poste mal nur den relevanten Bereich, kann hier nicht copy / paste arbeiten :kopfwand:
Code:
Config PortA = &B00110000
PortA = 1                                          'intern auf high 

Do
IF PinA.0 = 0 Then Goto A                      'springe zu A
Loop

A:
Do
IF PinA.1 = 0 Then Goto B                      'springe zu B
Loop

B:
Do
IF PinA.2 = 0 Then Goto C                      'springe zu C
Loop

C:
Do
IF PinA.3 = 0 Then Goto D                      'springe zu D
Loop

D: 
PortA.4 = 1                                                'mach was
wait 10
Porta.4 = 0                                        
Return
 

stonewood

Geowizard
upigors schrieb:
Also, ich präzisiere meine frage: Wenn ich den
Code:
$crystal = 1000000
wähle, stimmen dann die Sekunde/Millisekunden? Kanns leider nicht testen derzeit.
Beim Tiny13 ist die Einstellung 'ab Werk' 9,6 Mhz interner Oszillator, Teiler /8 aktiviert. Also 1,2 Mhz, +/- Toleranz. Damit als erster Versuch schon mal $crystal=1200000. Wie das beim Tiny24 ist kann ich aus dem Kopf nicht sagen -> Datenblatt. Und ja, darauf reagieren unter anderem die waitms-Befehle, die machen nichts anderes als 'zähle X takte' anhand von $crystal.

Als Beispiel für die Toleranz sollte man sich mal den 128 Khz-Oszillator ansehen, der tut mit $crystal=116000 einigermaßen sekundengenau seine waitms.
 

upigors

Geowizard
Danke an alle 3 "Erklärer" :gott:
ich glaub jetzt hats KLICK gemacht.... :D
Werde mal ein wenig spielen gehen nachher....
 

peter51d

Geocacher
ich habe mal upigors Code schnipsel auf einem Tiny 13 probiert.
Das Problem scheint in der Konfiguration der PullUp's zu liegen.
Mit
Code:
PortA=1
geht die Led nach kurzer Zeit von alleine an.

Mit
Code:
PortA=&a11001111
läüft es dann problemlos. Hier werden jetzt definiert nur die PullUp's für die Eingänge gesetzt.
 

Windi

Geoguru
@Upigors:
PortA = 1 ist das gleiche wie PortA=&B00000001
Du setzt damit nur Pin A0 auf High. Pin A1, A2 und A3 sind Low.
Sobald du jetzt A0 auf GND legst springt dein Programm weiter zu A:
Da er die anderen Pins jetzt als Low erkennt rennt dein Programm durch.
Wie Peter 51 schrieb muss es "PortA=&B00001111" heissen.
Dezimalschreibweise wäre dann PortA = 15.

Am Programmende verwendest du auch noch ein "Return".
Das würde ich auch noch rausnehmen und durch ein "End" ersetzen ansonsten kann den Programm evtl. an irgendeiner Stelle weiterlaufen.
Return macht nur dann Sinn wenn du vorher mit Gosub hingesprungen bist.
 

upigors

Geowizard
Danke ihr 2
Ich dachte mit
Code:
Port.A = 1
ziehe ich alle Ausgänge des Ports auf High :kopfwand:
Na ja, dann eben jeden einzelnen und schön. :D
werde es nachher gleich mal testen.
Danke nochmals
 

upigors

Geowizard
nehmen wir mal das normale Programm, reaktiv mit 7 Segment Anzeige
Ich grübele grad (ohne der Möglichkeit das zu testen im Moment) ob es auch möglich ist aus einem Pool von 10 unterschiedlichen Ausgaben (a 10 Zeichen) immer eine anzuzeigen. Also quasi oben irgendwie nen Zähler und unten mehrere Data-Blöcke und bei jedem anleuchten, tasten oder was auch immer wird nacheinander eine der 10 Ausgaben angezeigt. Oder akzeptiert Bascom nur 1x DATA:?
Gibts dann ne andere praktikable Lösung? Ich denke mit 10 Unterprogrammen in die man springt komme ich schnell an die Grenzen des Flash wenn eine Anzeige aus 10 Zeichen besteht und ich die quasi via gosub/goto "anspringe"
weiß nicht wie ich das besser beschreiben soll..... versteht mich jemand? :???:
 

chrysophylax

Geomaster
Ich versuch mich mal als Ratgeber-Eunuch ("Ich weiß theoretisch wie es geht, hab es noch nie gemacht, werd es auch nie machen können, aber tu mal so als könnte ich beim Thema mitreden"):

Meine Magnetbakensoftware im Tiny24 ist in Assembler mit 254 Zeichen Ausgabetext bei knapp über 30% Füllstand des Prozessors angekommen. Ich vermute also mal, mit sinnvollem Haushalten und Einsatz entsprechend kluger Befehlskonstrukte muss das auch in Basic gehen, so schlecht kann der Bascom-Murx-Compiler gar nicht sein.

Ein googeln nach "bascom flash konstanten" führt relativ schnell zum Befehl Lookup für im Flash abgelegte Daten, und zur offiziellen Hilfeseite.

Und so stellt sich der Eunuch vor, wie er Sex haben könnte, wenn er denn auf so obskure Sexualpraktiken wie Basic stehen würde:

1. Schritt: Verpacken jedes Anzeige-Zeichens in ein Einzelbyte. Eine Siebensegmentanzeige hat 7 Segmente und einen Dezimalpunkt, oh Wunder, das ergibt genau die 8 Bits die in ein Byte passen. Man definiere sich eine Unterroutine, die mit dem Byte als Parameter aufgerufen wird und die einzelnen Bits auf die unterschiedlichen Bitwertigkeiten von Port A und B auseinanderklambüsert. Wenn man den Dezimalpunkt nicht nutzen will, lässt man das achte Bit unbenutzt - ich hab ihn auf SCL am ISP-Verbinder gelegt, das war noch frei und stressfrei zu benutzen. Wenn ihr mir einen Stein in den Garten werfen wollt nehmt ihr das Signal auch, dann bleibt unsere Hard- und Software auch weiterhin kompatibel.

2. Schritt: Ablegen der 10 Textkonstanten-Blöcke im Flash, alle in gleicher Länge hintereinander. Nicht benötigte Textstücke werden mit Leerzeichen aufgefüllt. Dann belegen z.B. 10 Blöcke á 20 Zeichen 200 Byte Flash - ein Hauch von gar nix.

3. Schritt: Ein Zeiger speichert die Position im Textkonstanten-Gesamtblock. Bei jedem Trigger wird eine Unterroutine aufgerufen, die 20 mal je ein Zeichen per Schleife und Lookup aus dem Flash holt, den Zeiger inkrementiert, das Zeichen der Unterroutine zur Ausgabe vorwirft, und anschließend eine immer konstante gleiche (Anzeige-)Zeit wartet. Das Warten könnte man, je nach persönlicher Vorliebe, gleich in die Ausgabe-Unterroutine werfen.

4. Schritt: Nach der Ausgabe der 20 Zeichen wird ein "Triggerzähler" um 1 erhöht. Wenn der Zählerstand 10 erreicht, wird der Triggerzähler auf 0 gesetzt und der Zeiger für den Textkonstanten-Gesamtblock ebenso. So erreicht man, dass nach Ausgabe von 10 verschiedenen Blöcken wieder der erste (Position 0) ausgegeben wird. Nach Bearbeitung des Triggerzählers warten auf die nächste Auslösung.

So würde ich es ressourcenschonend machen. Kann auch in Bascom nicht so schlimm sein. In Assembler wars ein Klacks. Da hab ich es schon genau so gemacht, allerdings nur mit einer einzigen dafür bis zu 254 Zeichen langen Botschaft.

Es gibt dann halt nur einen einzigen Data-Bereich, und der Benutzer hat dafür Sorge zu tragen, dass die Texte alle gleich lang sind und notfalls aufgefüllt werden.

chrysophylax.
 

upigors

Geowizard
Danke für deine ausführlichen Ausführungen.
Da muß ich mich wohl tatsächlich intensiver mit beschäftigen.....
Wenn ich den Kopf etwas frei hab geh ich das mal an.
mal sehen was bei raus kommt ...
nochmals danke und gruß
uwe
 

chrysophylax

Geomaster
Nur so als eine von beliebig vielen Möglichkeiten, wie man sowas machen kann.

Die Knackpunkte zum speichersparen sind glaub ich folgende :

- Ein Anzeigezeichen wird immer nur durch einen einzelnen Byte-Wert repräsentiert,

- Eine Unterroutine übernimmt das auseinanderdröseln der einzelnen Segmente, die Ausgabe auf die Ports, und das Abwarten der Anzeigedauer

- Die Zeichen werden in einem Konstanten-Array im Flash abgelegt und in einer Schleife abgeholt statt wie bisher ein Konstrukt ähnlich ("Pseudo-Code", man sehe mir meine Sprachunzulänglichkeiten nach):
Code:
PORTA = &b[A-Anteil von Zeichen 1]
PORTB = &b[B-Anteil von Zeichen 1]
Reset Watchdog
Powerdown
Porta = 0
Portb = 0
  
PORTA = &b[A-Anteil von Zeichen 2]
PORTB = &b[B-Anteil von Zeichen 2]
Reset Watchdog
Powerdown
Porta = 0
Portb = 0


PORTA = &b[A-Anteil von Zeichen 3]
PORTB = &b[B-Anteil von Zeichen 3]
Reset Watchdog
Powerdown
Porta = 0
Portb = 0

Ich vermute mal, eine erhebliche Menge Speicher würde man schon sparen, wenn man das Ganze erheblich wartungsfreundlicher aber dafür mit erheblich mehr Quellcode unter geschickter Nutzung von Konstanten ungefähr folgendermaßen formuliert (Wieder "Pseudo-Basic-Code" quasi-übersetzt aus meinem CharROM.inc in Assembler, bitte selbst für die richtige Syntax sorgen) :

Code:
' +--------------------------------------------------------------------------+
' |          Vordefinierte Segmente für Ausgabe auf 7Segment-Anzeige         |
' +--------------------------------------------------------------------------+
CONST SEG_a   = &h01'   oben quer          -------
CONST SEG_b   = &h02'   oben rechts       |   a   |
CONST SEG_c   = &h04'   unten rechts      |f     b|
CONST SEG_d   = &h08'   unten quer        |       |
CONST SEG_e   = &h10'   unten links        -------
CONST SEG_f   = &h20'   oben links        |   g   |
CONST SEG_g   = &h40'   mitte quer        |e     c|
CONST SEG_DP  = &h80'   Dezimalpunkt      |   d   |
'                                          -------  O DP

CONST SYM_1 = SEG_b | SEG_c
CONST SYM_2 = SEG_a | SEG_b | SEG_d | SEG_e | SEG_g
CONST SYM_3 = SEG_a | SEG_b | SEG_c | SEG_d | SEG_g

DIM Zeichen AS Byte

Ausgabe:
  if ((Zeichen & SEG_a)>0) then PORTB.0=1
  if ((Zeichen & SEG_b)>0) then PORTB.1=1
  if ((Zeichen & SEG_c)>0) then PORTB.2=1
  if ((Zeichen & SEG_d)>0) then PORTA.1=1
  if ((Zeichen & SEG_e)>0) then PORTA.7=1
  if ((Zeichen & SEG_f)>0) then PORTA.0=1
  if ((Zeichen & SEG_g)>0) then PORTA.3=1
  if ((Zeichen & SEG_DP)>0) then PORTA.4=1
  Reset Watchdog 
  Powerdown
  Porta = 0
  Portb = 0
Return

Zeichen = SYM_1
Gosub Ausgabe
Zeichen = SYM_2
Gosub Ausgabe
Zeichen = SYM_3
Gosub Ausgabe

Das gibt nacheinander relativ speichersparend die Zahlen 1 bis 3 (ich war zu faul mehr zu definieren, das langt glaub ich um das Muster zu erkennen) auf der Anzeige aus.

Damit dürfte schonmal ein erheblicher Schritt getan sein. Keine Garantie auf syntaktische Korrektheit, ich hab nur mal flüchtig über das reaktivlicht-Wiki drübergeschaut. Insbesondere für die richtige Formulierung logischer Verknüpfungen in Basic übernehme ich keine Haftung ;)

Das geht alles noch viel eleganter zu formulieren (gerade die if´s), aber dazu fehlt mir der Nerv mich tief genug in die Sprachstruktur einzulesen.

chrysophylax.de
 

upigors

Geowizard
ein eigentlich recht simples ding aber ich bekomme graue haare. keine idee mehr wo ich ansetzen muss. hier erstmal der m.E. relevante Teil vom Code:
Code:
Dim A As Byte
Dim B As Byte
Dim Z As Byte                                               'Variablen definieren
Z = 0                                                       'zähler auf Null

Do

Wdtcsr = &B11010011
Reset Watchdog
Powerdown

      If Pina.2 = 1 Then
      Gosub X
      Else
      End If
Loop

X:
Z = Z + 1
Wdtcsr = &B11010110

If Z = 0 Then Return                     'kann ja eigentlich nicht sein aber stört wohl auch nicht
If Z = 1 Then Gosub P1
If Z = 2 Then Gosub P2
If Z = 3 Then Gosub P3
If Z = 4 Then Gosub P4
If Z = 5 Then Gosub P5
If Z = 6 Then Gosub P6
If Z = 7 Then Gosub P7
If Z = 8 Then Gosub P8
If Z = 9 Then Gosub P9
If Z = 10 Then Gosub P10
If Z = 11 Then Gosub P11
If Z = 12 Then Gosub P12
If Z = 13 Then Gosub P13
If Z = 14 Then Gosub P14
If Z = 15 Then Gosub P15
If Z = 16 Then Gosub P16
If Z = 17 Then Gosub P17
If Z = 18 Then Gosub P18

If Z = 19 Then Gosub P0

Wdtcsr = &B11110000
Portb = &B00000000
Porta = &B00000000
For B = 1 To 2
Reset Watchdog
Powerdown
Reset Watchdog
Powerdown
Next B
Wdtcsr = &B11010110

Return

P0:

Z = 0                                                        'zähler auf null
Portb = &B00000000
Porta = &B00000000
Reset Watchdog
Powerdown
Return

P1:

Portb = &B00000111                                          '4
Porta = &B00001000
Reset Watchdog
Powerdown
Portb = &B00000111                                          '8
Porta = &B10001011
Reset Watchdog
Powerdown
Portb = &B00000110                                          '3
Porta = &B00001011
Reset Watchdog
Powerdown
Portb = 0
Porta = 0
Reset Watchdog
Powerdown

Return

P2:

Portb = &B00000010                                          '2
Porta = &B10001011
Reset Watchdog
Powerdown
Portb = &B00000111                                          '5
Porta = &B00000011
Reset Watchdog
Powerdown
Portb = &B00000100                                          '7
Porta = &B00001001
Reset Watchdog
Powerdown
Portb = 0
Porta = 0
Reset Watchdog
Powerdown

Return

P3:

Portb = &B00000110                                          '3
Porta = &B00001011
Reset Watchdog
Powerdown
Portb = &B00000111                                          '6
Porta = &B10000011
Reset Watchdog
Powerdown
Portb = &B00000010                                          '2
Porta = &B10001011
Reset Watchdog
Powerdown
Portb = 0
Porta = 0
Reset Watchdog
Powerdown

Return

P4:

Portb = &B00000110                                          '3
Porta = &B00001011
Reset Watchdog
Powerdown
Portb = &B00000010                                          '2
Porta = &B10001011
Reset Watchdog
Powerdown
Portb = &B00000111                                          '9
Porta = &B00001011
Reset Watchdog
Powerdown
Portb = 0
Porta = 0
Reset Watchdog
Powerdown

Return

P5:

...................................das geht jetzt bis 18 so weiter.........................................

was soll passieren? Bei jedem Tasten soll der Zähler einen weiter springen und so nacheinander alle 19 Dreierzahlenblöcke anzeigen, zwischendurch mit "Zwangspause". Danach Zähler wieder auf Null und von Vorn der Spaß.
Was passiert? Die ersten beiden 3er Blöcke ( 483, 257) werden angezeigt, der 3. (362) auch noch und dann wieder der erste (482) ohne pause ect.... und das ganze immer im kreis. Die Tasterabfrage ist also ok und auch Am Anfang tut das Programm was es soll aber dann.... Als ob es abbricht/abstürzt/resetet.....
Kann mal jemand drüber schauen? Mir sind die Ideen vor 2h ausgegangen. Hab schon zusätzlichen Schnickschnack wie die 3fache Widerholung der Zahlen raus genommen um es übersichtlich zu haben aber ich seh einfach das Problem nicht.
 

upigors

Geowizard
Selber gelöst....
Code:
If Pina.2 = 1 Then
      Gosub X
      End If
so gehts, aber vielleicht hat noch jemand ne idee warum bzw. warum vorher nicht????

Edit: das wars wohl doch nicht, Problem trat wieder auf.... hätte mich auch gewundert.....
ABER ich hatte auf dem steckbrett die 7 segment anzeige ohne vorwiderstand an 3V. Anscheinend hat tatsächlich der controller sich immer genau an der stelle "abgeschaltet". seit da ein 50 ohm dazwischen ist geht es....
 

Lion251

Geocacher
Sind die Batterieleiter länger als ein paar cm?
Dann kann es passieren dass bei ein/ausschalten Peaks auf die Versorgungsspannung entstehen.
Vor allem, wenn mehrere LEDs ohne Vorwiderstand gleichzeitig schalten.
Ich hatte genaus dasselbe Problem.
Über die Versorgungsspannung (direkt an den Prozessorpins!) ein keramischer C von 100 nF, und parallel dazu 10-100 uF Alu-Elko. Ohne Elko kann es noch zu Schwingungen zwischen die Induktivität der Leitungen (bei mir 50 cm bis Labornetzteil) und keramischer C kommen.
Bei mir hat's so geholfen, aber ohne C's und kurze Batterieleitungen (<5 cm) ging auch.
Manchmal sind "Angstkondensatoren" doch nicht überflüssig!
 
Oben