für xorg1990

tsseh

Lounge-Member
Und das soll sich auf die Übertragungsgeschwindigkeit auswirken?
nein, das war die erklärung, warum ich 100 und nicht 128 byte pro packet übertragen habe. die 28 byte könnten sich auf die übertragungsgeschwindigkeit auswirken, sind immerhin fast 1/3 mehr nutztdaten

Und dabei bin ich dahinter gekommen das die Audioqualität dann am besten ist, wenn der Prescaler auf 16 steht einspricht ~38Khz, wird die Wandlung schneller rauscht es, ist es langsamer sind die Frequenzen verschoben . Ist der Prescaler auf 128(das langsamste) geht gar nix los.
By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution.
keine ahnung wie groß deine cpu-freq. war. nicht jeder teiler macht da sinn. du hattest doch nur 8bit-auflösung? dann kannst du auch höher als 200kHz gehen - in grenzen.

Habe man eine frage zum Timer auf dem ESP. Timer0 und Timer1 sind Hardware Timer?
beim esp gibt es nur einen hw-timer, den darf man nicht ändern, weil der grundlage für alles ist, auch für die wlan übertragung

Wie bewege ich Timer 1 dazu alle 51microsec einen Interrupt zu feuern?
was heißt jetzt 51 µs? die auflösung ist immer in grenzen möglich, ob man überhaupt in die nähe von 51µs kommt wollten wir ganz am anfang mal testen, sind da aber abgestorben - es sah nicht so aus. timer 0/timer 1 ist was arduino spezifisches, das esp sdk hat nur ets_timer_arm_ne
w mit parameter 4 0, dann sind es µs. mit parameter 4 = 1 ms. die entsprechenden defines sind
#define os_timer_arm_us(a, b, c) ets_timer_arm_new(a, b, c, 0) // µs
#define os_timer_arm(a, b, c) ets_timer_arm_new(a, b, c, 1) // ms
ob das mit µs überhaupt geht und wenn ja, mit welcher auflösung der timer selbst läuft war nicht klar.
50 µs klingt aber sehr knapp.

- - - Aktualisiert - - -

Zum timer beim esp:
das 1. ist schon mal
Reoccurring timers should not be scheduled more often than every 5 ms.
zur auflösung, die ist abhängig davon ob du µs-timing aktiviert hast oder nicht
If system_timer_reinit has been called, the timer value allowed ranges from 100 to 0x689D0.
If system_timer_reinit has NOT been called, the timer value allowed ranges from 5 to 0x68D7A3.
das µs-timing selbst nach aktivierung:
unit: microsecond, the minimum value is 0x64, the maximum value allowed to input is 0xFFFFFFF.

beim HW-timer selbst ist erst mal nur die PWM erwähnt, die davon abhängig ist:
APIs in hw_timer.c can not be called when PWM APIs are in use, because they all use the same hardware timer.
ob das wirklich nur die pwm betrifft???
zur auflösung:
• In autoload mode:
- For FRC1_SOURCE, range: 50 ~ 0x199999 µs;
- For NMI_SOURCE, range: 100 ~ 0x199999 µs.
• In non autoload mode, range: 10 ~ 0x199999 µs.
probieren könntest du also mal
Code:
hw_timer_init(FRC1_SOURCE, 1);
hw_timer_set_func(hw_timer_cb);
hw_timer_arm(50);
zu beachten ist noch, daß das cb nicht im flash liegen darf
The hardware timer callback function must NOT be defined with ICACHE_FLASH_ATTR.
ich bin mir nicht sicher, dachte aber bei arduino wird im gegensatz zum sdk erst mal alles in den flash gelegt und im iram-sagment landen nur mit "ICACHE_RAM_ATTR" oder ähnliches gekennzeichnete funktionen.
 

xorg1990

New member
tsshe schrieb:
die 28 byte könnten sich auf die übertragungsgeschwindigkeit auswirken, sind immerhin fast 1/3 mehr nutztdaten
Ok, ich probiere das wenn ich lust habe mal aus mit den 100byte.

keine ahnung wie groß deine cpu-freq. war. nicht jeder teiler macht da sinn. du hattest doch nur 8bit-auflösung? dann kannst du auch höher als 200kHz gehen - in grenzen.
8Mhz F_CPU. Die Vorteiler können von 64 bis 8 gehen, die Ausgabe ist immer noch verständlich. Bei Vorteiler auf 16 finde ich die Ausgabe am besten/klarsten.

tsseh schrieb:
beim esp gibt es nur einen hw-timer, den darf man nicht ändern, weil der grundlage für alles ist, auch für die wlan übertragung
Asso, aber das würde ja bedeuten, dass eine ISR die Main loop blockiert, oder eine lange schleife in der loop die isr blockiert.

tsseh schrieb:
was heißt jetzt 51 µs? die auflösung ist immer in grenzen möglich, ob man überhaupt in die nähe von 51µs kommt wollten wir ganz am anfang mal testen, sind da aber abgestorben - es sah nicht so aus. timer 0/timer 1 ist was arduino spezifisches, das esp sdk hat nur ets_timer_arm_ne
w mit parameter 4 0, dann sind es µs. mit parameter 4 = 1 ms. die entsprechenden defines sind
#define os_timer_arm_us(a, b, c) ets_timer_arm_new(a, b, c, 0) // µs
#define os_timer_arm(a, b, c) ets_timer_arm_new(a, b, c, 1) // ms
ob das mit µs überhaupt geht und wenn ja, mit welcher auflösung der timer selbst läuft war nicht klar.
50 µs klingt aber sehr knapp.
Das weiß ich alles. Ich wollte nur mal einen etwas Präziseren Timer nehmen, da irgend wo irgendwas noch schief läuft, die Soundausgabe im Browser also die Daten vom avr adc sind irgendwie falsch, das ganze hört sich sehr Krazig an.

Bei einer Samplerate von 19230Hz sind das 153840 bit/s. Setze ich die SPISettings auf 153840, kommt der Watchdog. Deshalb habe ich das mal 2 genommen geht.
in einer isr aller 51µs mache ich dann den Transfer. 1/19230Hz == 51µs.
Aber ist das so richtig?
SPI.beginTransaction(SPISettings(307680, MSBFIRST, SPI_MODE0));



tsseh schrieb:
ob das wirklich nur die pwm betrifft???
Für die WLAN generierung ist ein/eine PLL verantwortlich, das habe ich irgendwo gelesen. Da ich mich immer noch frage wie die auf die 2,5 Ghz kommen.

tsseh schrieb:
ich bin mir nicht sicher, dachte aber bei arduino wird im gegensatz zum sdk erst mal alles in den flash gelegt und im iram-sagment landen nur mit "ICACHE_RAM_ATTR" oder ähnliches gekennzeichnete funktionen.
Die ganze arduino ide Reglung ist bei den esp aufgehebelt.
 

tsseh

Lounge-Member
Ok, ich probiere das wenn ich lust habe mal aus mit den 100byte.
nein, du verstehst mich falsch.
ich habe das einfach mal probiert mit den websockets auf dem esp, weil ich nicht glauben wollte, daß das nicht gehen soll.
dazu habe ich das websocket-protokoll mit wenig aufwand implementiert. und einfach alles was mehr arbeit als notwendig war weggelassen.
deswegen habe ich das mit 100byte probiert. und es ging. das das mit 28 byte mehr deutlich langsammer gehen wird glaube ich nicht, bzw. habe ich das zwischenzeitlich auch schon getestet - allerdings habe ich jetzt irgendwo noch einen fehler drinn und zum debuggen nicht die rechte lust. es gehen jetzt 2 pakete hin und her, dann bricht die verbindung ab.

8Mhz F_CPU. Die Vorteiler können von 64 bis 8 gehen, die Ausgabe ist immer noch verständlich. Bei Vorteiler auf 16 finde ich die Ausgabe am besten/klarsten.
ok, dann nimm die 16

Asso, aber das würde ja bedeuten, dass eine ISR die Main loop blockiert, oder eine lange schleife in der loop die isr blockiert.
nein, das bedeutet, daß wenn sich irgendjemand darauf verlässt, dass der hw-timer mit einer bestimmten frequenz lauft und du diese änderst schluss ist


Bei einer Samplerate von 19230Hz sind das 153840 bit/s. Setze ich die SPISettings auf 153840, kommt der Watchdog.
kann ich mir vorstellen

Deshalb habe ich das mal 2 genommen geht.
warum mal 2? durch 2

in einer isr aller 51µs mache ich dann den Transfer. 1/19230Hz == 51µs.
selbst das glaube ich nicht, dass das noch geht, alle 51µs ein byte übertragen und das ist ja nicht alles was du auf dem esp machst

Für die WLAN generierung ist ein/eine PLL verantwortlich, das habe ich irgendwo gelesen. Da ich mich immer noch frage wie die auf die 2,5 Ghz kommen.
das ist ja erst mal egal, das ist alles hardware. aber es muss zyklisch daten lesen und schreiben. entweder haben die noch einen "geheimen" internen timer, oder wifi geht dann einfach nicht mehr


Die ganze arduino ide Reglung ist bei den esp aufgehebelt.
???? der esp hat ein stück ram für befehlsabarbeitung - iram1 segment. in diesen werden beim booten die funktionen gelegt, welche im flasch auf adr 0 liegen (grob gesagt, da liegen auch noch die datensegmente)
alle funktionen welche mit ICACHE_FLASH_ATTR gekennzeichnet sind, landen im flash im irom0 segment.
das esp-sdk legt jetzt alle seine funktionen in den ram, der ist bei mir immer fast voll und ich kann kaum eigene funktionen in den ram legen und muss meine eigenen in den flash legen.
deswegen glaube ich, daß die leute die den arduino-core implementiert haben, das .text-segment welches sonst im ram landet auch in den flash gelegt haben und nur teile die mit "RAM_ATTR" irgendwas gekennzeichnet sind in den ram packen.
im ram müssen aber alle isr landen, weil du für den zugriff auf den flash auch wieder eine isr benötigst.
 

xorg1990

New member
tsseh schrieb:
nein, du verstehst mich falsch.
Asso, du hast dir deine eigne Websocket lib erstellt. Und warum das Rad neu erfinden ist doch alles da.


tsseh schrieb:
ok, dann nimm die 16
Nope, da bräuchte ich eine externen quarz und am attiny ist keine Pin mehr frei.

tsseh schrieb:
warum mal 2? durch 2
Das ergibt ja kein sinn, damit macht man die SPI Übertagung noch langsamer.

tsseh schrieb:
selbst das glaube ich nicht, dass das noch geht, alle 51µs ein byte übertragen und das ist ja nicht alles was du auf dem esp machst
Doch das geht prima. Das senden der Daten vom esp zum attiny geht ja perfekt. Andersrum kommt gülle raus die SPI Daten die vom atttiny zum ESP kommen sind Müll.

Es liegt aber nicht an der Übertagung. Die ADC Wandlung am attiny läuft schief, eben das Problem was ich anfangs schon mal hatte nur in die andere Richtung. Also wenn der ADC aktiv war, dann war die PWM Ausgabe gülle.

Es besteht also irgendwie ein Hardware Konflikt zwischen usi und adc. Allerdings kann ich im Internet nix finden, dass es da Probleme gibt oder zumindest jemand anders das Problem hat.

Mittlerweile habe ich alles durch exerziert. mit usi isr ohne, ohne adc isr, adc Einzelmessung in der loop.. usw.
 

tsseh

Lounge-Member
Asso, du hast dir deine eigne Websocket lib erstellt. Und warum das Rad neu erfinden ist doch alles da.
ich hab keine gefunden

Nope, da bräuchte ich eine externen quarz und am attiny ist keine Pin mehr frei.
wieso?
edit:
also wieso brauchst du einen externen quarz, nicht wieso ist kein pin mehr frei. (mal davon abgesehen was ein quarz an einem pin bringen soll)
/tide

Das ergibt ja kein sinn, damit macht man die SPI Übertagung noch langsamer.
ja, ich dachte das ist das ziel, wiel schon ohne dopplung der wotchdog kommt

Es liegt aber nicht an der Übertagung. Die ADC Wandlung am attiny läuft schief, eben das Problem was ich anfangs schon mal hatte nur in die andere Richtung. Also wenn der ADC aktiv war, dann war die PWM Ausgabe gülle.
ja

Es besteht also irgendwie ein Hardware Konflikt zwischen usi und adc. Allerdings kann ich im Internet nix finden, dass es da Probleme gibt oder zumindest jemand anders das Problem hat.
frag mal bei avrfreaks

- - - Aktualisiert - - -

waren wir nicht da stehen geblieben, dass es eher auf der esp seite lag? ich lese mir morgen nochmal die alten beiträge durch

- - - Aktualisiert - - -

hast du das
dann würde ich testen, ob es am avr oder esp liegt. einfach einen 2. avr verbinden der nichts anderes macht als 0 zu schicken.
wenn dann das problem immer noch auftritt, hast du ein problem.
mal probiert?
 
Zuletzt bearbeitet:

xorg1990

New member
tsseh schrieb:
ich hab keine gefunden
https://github.com/Links2004/arduinoWebSockets


tsseh schrieb:
(mal davon abgesehen was ein quarz an einem pin bringen soll)
Quarze werden an XTAL1 und XTAL2 angeschlossen. Zusätzlich ist es erforderlich, zwei Folienkondensatoren anzuschließen.
Homepage Uwe Freese - Leiser Rechner

tsseh schrieb:
ja, ich dachte das ist das ziel, wiel schon ohne dopplung der wotchdog kommt
nee, der WDT kommt wenn die SPI Frequenz zu langsam gewählt wird nach oben hin sind "keine Grenzen".

tsseh schrieb:
frag mal bei avrfreaks
Oder Mikrocontroller.de

tsseh schrieb:
waren wir nicht da stehen geblieben, dass es eher auf der esp seite lag? ich lese mir morgen nochmal die alten beiträge durch
nee, der esp ist nicht schnelle genug die Wlan Verbindung zu toggeln und halt das die Timer gülle sind.
Habe was zu den Timern gefunden:
https://github.com/esp8266/Arduino/issues/2426

Ob nun Timer0 ein HW Timer ist oder nicht egal, er ist nahezu akkurat.


tsseh schrieb:
Ja, konnte da nichts auffälliges feststellen.

Mein Debugging Vorgang bisher war:

1tes
Erstmal grundsätzlich klären ob die gesampelten Werte überhaupt in Ordnung sind. Geht.
2tens
Die SPI Übertragung geprüft, eine Wert hin geschickt auf dem avr verdoppelt und zurück gesendet. Geht. Allerdings an der stelle habe ich nicht mehr überprüft was der adc macht. Das kommt jetzt.

3tens.
Schritt 1 wiederholt, dieses mal zusätzlich eine SPI Übertragung gestartet. Und haha, sobald ich den Clock pin anschließe knatteret und Rauscht es wie verrückt. Ergo bockt die USI den ADC. Aber wenn ich den ADC Pin auf GND ziehe ist 0 und bei Vreff kommt 255 also irgenwie geht er noch aber eben nicht richtig. Die Spi Übertragung läuft ebenfalls problemlos.

Meine idee entweder i2c/twi nutzen (eventulle geht das ja) oder eine Software SPI nutzen.
 

tsseh

Lounge-Member
das ist aber für arduino



Quarze werden an XTAL1 und XTAL2 angeschlossen. Zusätzlich ist es erforderlich, zwei Folienkondensatoren anzuschließen.
ja und? die frage ist ja was du mit dem quarz an einem gpio willst?


nee, der WDT kommt wenn die SPI Frequenz zu langsam gewählt wird nach oben hin sind "keine Grenzen".
warum soll der wd kommen wenn die spi freq. zu langsam ist? und nach oben sind natürlich grenzen. z.b. wenn die daten so schnell kommen, dass der esp sie nicht mehr verarbeiten kann, weil der int ständig zuschlägt und dann der wd kommt.


nee, der esp ist nicht schnelle genug die Wlan Verbindung zu toggeln
das wlan alleine ist erst mal schnell genug wie mein test gezeigt hat.

Ob nun Timer0 ein HW Timer ist oder nicht egal, er ist nahezu akkurat.
im 1,5 sek bereich - und es gibt abweichungen im ms bereich - gut, das ist bei 1,5 s nicht tragisch, die frage ist, wie sieht es bei 5ms aus und bei 50µs

- - - Aktualisiert - - -

ja und? die frage ist ja was du mit dem quarz an einem gpio willst?
ok, du meinst nicht gpio sondern tatsächlich als externen quarz - gut, aber was soll das bringen?

- - - Aktualisiert - - -

hast du das CKDIV8-fuse-bit zurückgesetzt? das steht per default auf enabled.
entweder musst du das disablen oder CLKPS[0-3] auf 0 setzen im Clock Prescale Register

- - - Aktualisiert - - -

Also wenn der ADC aktiv war, dann war die PWM Ausgabe gülle.
da stimmt auch einiges nicht. du nutzt ja die asynchrone clock source
PCK Enable:
It is safe to set this bit only when the PLL is locked i.e the PLOCK bit is 1.
The bit PCKE can only be set, if the PLL has been enabled earlier.
also
Code:
PLLCSR |= (1 << PLLE);    // PLL enable

while ((PLLCSR & (1 << PLOCK)) == 0x00){} // warten auf sync
PLLCSR |= (1 << PCKE); // Enable asynchronous mode
dann sehe ich nicht, wo du OCR1C setzt, dein counter sollte ständig im overflow hängen
 

xorg1990

New member
tsseh schrieb:
das ist aber für arduino
was stört dich daran?

tsseh schrieb:
warum soll der wd kommen wenn die spi freq. zu langsam ist? und nach oben sind natürlich grenzen. z.b. wenn die daten so schnell kommen, dass der esp sie nicht mehr verarbeiten kann, weil der int ständig zuschlägt und dann der wd kommt.
Warum der wdt kommt weiß ich doch nicht. Für mich gibt es eine Option SPI Settings, der Rest hat dann zu funktionieren.

tsseh schrieb:
ja und? die frage ist ja was du mit dem quarz an einem gpio willst?
ich bin beim avr nicht beim esp.

tsseh schrieb:
ok, du meinst nicht gpio sondern tatsächlich als externen quarz - gut, aber was soll das bringen?
Die von dir genannten 16Mhz.


tsseh schrieb:
das wlan alleine ist erst mal schnell genug wie mein test gezeigt hat.
Ja, 100byte .

tsseh schrieb:
hast du das CKDIV8-fuse-bit zurückgesetzt? das steht per default auf enabled.
entweder musst du das disablen oder CLKPS[0-3] auf 0 setzen im Clock Prescale Register
#
Von den Fuses her, habe ich nur die von der Taktung gesetzt.

tsseh schrieb:
da stimmt auch einiges nicht. du nutzt ja die asynchrone clock source
Asso, das lag an dieser Zeile: USISR = (1 << USIOIF);
Die musste ganz an das Ende von den USI Gedöns. ich vergaß.

tsseh schrieb:
dann sehe ich nicht, wo du OCR1C setzt, dein counter sollte ständig im overflow hängen
Warum OCR1C?

Hier nochmals der aktuelle code (beachte bitte den auskommentierten Sachen)
Code:
#define F_CPU 8000000UL
#include "pins_arduino.h"

/*
  #define bufferSize 128
  #define BUFFER_MASK (bufferSize-1)

  Pinmodes
  PB0 MOSI
  PB1 MISO
  PB2 Clock
  PB3 ADC Input
  PB4 PWM Out
*/

volatile byte adcValue = 0;
volatile byte incommingByte = 0;


void setup() {
  //pinModes
  pinMode(0, INPUT);// initialize the MOSI Port (PIN 0)
  pinMode(1, OUTPUT);// initialize the MISO Port (PIN 1)
  pinMode(2, INPUT);// initialize the SCK Port (PIN 2)
  pinMode(4, OUTPUT);
  pinMode(3, INPUT);


  cli();
  // Enable 64 MHz PLL and use as source for Timer1
  PLLCSR = 1 << PCKE | 1 << PLLE;
  // Set up Timer/Counter1 for PWM output
  TIMSK = 0;                              // Timer interrupts OFF
  TCCR1 = 1 << CS10; //1<<PWM1A | 2<<COM1A0 | 1<<CS10; // PWM A, clear on match, 1:1 prescale
  GTCCR = 1 << PWM1B | 2 << COM1B0;       // PWM B, clear on match
  OCR1B = 128;               // 50% duty at start on pin PB4
  // Set up Timer/Counter0 for 44.1kHz interrupt to output samples.
  /*
    TCCR0A = 3 << WGM00;                    // Fast PWM sets bits WGM00 and WGM01, which (when combined with WGM02 from TCCR0B below) enables Fast PWM mode
    TCCR0B = 1 << WGM02 | 2 << CS00;        // 1/8 prescale
    TIMSK = 1 << OCIE0A;                    // Enable compare match
    OCR0A = 51;                            // 19kHz Fs
  */
  USICR = (1 << USIWM0) // SPI mode; Uses DO, DI, and USCK pins.
          | (1 << USIOIE) // Enable interrupt
          | (1 << USICS1) // Clock is external postivie flanke
          | (0 << USICS0); // SPI Mode 0

  //ADC settings 8bit value
  ADMUX =   3 | //channel 3
            (1 << ADLAR) |     // left shift result
            (0 << REFS1) |     // Sets ref. voltage to internal 3.3V, bit 1
            (0 << REFS0) ;     // Sets ref. voltage to internal 3.3V, bit 0

  ADCSRA =
    (1 << ADEN)  |     // Enable ADC at 38461 Hz Samplerate
    (1 << ADSC)    | // start conversion
    //(1 << ADATE)   | // free running
    (1 << ADPS2) |     // set prescaler to 16, bit 2
    (0 << ADPS1) |     // set prescaler to 16, bit 1
    (0 << ADPS0) ;     // set prescaler to 16, bit 0
    //(1 << ADIE); //enabel adc isr
  sei();  // enable interrupts

  ADCSRA |= (1 << ADSC);            // Start the first conversion
  while (ADCSRA & (1 << ADSC) )         // auf Abschluss der Konvertierung warten
  {
  }

  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
     Wandlung nicht übernommen. */
  (void) ADCH;
}

/*
ISR(ADC_vect) { // interuppt each 38461Hz
  adcValue = ADCH;
  //ADCSRA |= (1 << ADSC);        // Start the next conversion
}


  // Sample interrupt 19khz
  ISR(TIMER0_COMPA_vect) {
  OCR1B = (byte)sample/2;//pwm 0to50%
  }

*/

  ISR(USI_OVF_vect) {
  incommingByte = USIDR;
  OCR1B = (byte)incommingByte / 2;

  USIDR = adcValue;
  
  // Clear counter overflow flag so next byte can begin arriving
  // While we're processing this one
  USISR = (1 << USIOIF);

  }


void loop() {
  ADCSRA |= (1 << ADSC);            // Start the first
  while (ADCSRA & (1 << ADSC) )         // auf Abschluss der Konvertierung warten
  {
  }
  adcValue = ADCH;
 /*
  // Wait for complete byte to arrive
  while ((USISR & (1 << USIOIF)) == 0) {}
  OCR1B = (byte) USIDR  / 2;
  USIDR = adcValue;
  // Clear counter overflow flag so next byte can begin arriving
  // While we're processing this one
  USISR = (1 << USIOIF);
*/
}

- - - Aktualisiert - - -

xorg1990 schrieb:
Von den Fuses her, habe ich nur die von der Taktung gesetzt.

Ist CKDIV8 nicht der Systemtakt.
 
Zuletzt bearbeitet:

tsseh

Lounge-Member
was stört dich daran?
dass ich mit dem esp bisher nur mit dem sdk gearbeitet habe

Warum der wdt kommt weiß ich doch nicht. Für mich gibt es eine Option SPI Settings, der Rest hat dann zu funktionieren.
naja


ich bin beim avr nicht beim esp.
ich auch


Die von dir genannten 16Mhz.
ich meinte den prescaler 16, von dem du sagst der geht am besten

ja und? du wolltest doch kleine pakete, mit 8k kann ich das auch mal probieren bei gelegenheit, ich behaupte mal das geht auch

Asso, das lag an dieser Zeile: USISR = (1 << USIOIF);
Die musste ganz an das Ende von den USI Gedöns. ich vergaß.
das sollte egal sein


weil OCR1C festlegt bis wohin gezählt wird

Ist CKDIV8 nicht der Systemtakt.
der teiler, ist der enabled läuft die cpu mit 1 MHz
 

tsseh

Lounge-Member
Die von dir genannten 16Mhz.
die 16MHz bekommst du übrigens auch ohne externe taktquelle hin

High Frequency PLL Clock
There is an internal PLL that provides nominally 64 MHz clock rate locked to the RC Oscillator for the use of the
Peripheral Timer/Counter1 and for the system clock source. When selected as a system clock source, by programming
the CKSEL fuses to ‘0001’, it is divided by four like shown in Table 6-4.
 

xorg1990

New member
tsseh schrieb:
]ja und? du wolltest doch kleine pakete, mit 8k kann ich das auch mal probieren bei gelegenheit, ich behaupte mal das geht auch
Ich nicht.

tsseh schrieb:
]weil OCR1C festlegt bis wohin gezählt wird
Das macht OCR0A, aber das nutze ich nicht mehr, da ich die Ringbuffer nicht mehr nutze, ich schreibe die Samples direkt in OCR1B, geht auch.

tsseh schrieb:
]der teiler, ist der enabled läuft die cpu mit 1 MHz
Asso, ja das ist disabled, weil mit 1Mhz rastet die PLL nicht ein.

tsseh schrieb:
die 16MHz bekommst du übrigens auch ohne externe taktquelle hin
Ja, dann kann ich aber die PLL nicht mehr als Timer Source verwenden.

Die Änderung an der PLL die du genannt hast habe ich gemacht, ändert aber nichts an der Mangelhaften ADC Qualität.

Den HW Timer für den esp bekomme ich nicht kompeliert da kommt immer:

NmiTimSetFunc' was not declared in this scope
NmiTimSetFunc(func)


Weiß nicht welche .h Datei mir fehlt.

Der code für Timer 0 und Timer1 steht hier.
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/core_esp8266_timer.c

Bei den HW Timer ist so wenn der auf FRC1_SOURCE steht ist tatsächlich das WLAN behindert oder eher der Timer wenn das WLAn ein ist.
Deswegen geht auch die PWM Ausgabe auf den esp nicht. Man soll stattdessen NMI SOURCE irgendwas nehmen das geht.

Habe ich so zumindest in einem espressif Forum gelesen.
 

tsseh

Lounge-Member
Senden und Empfangen tue ich aber jeweils nur 128byte große chunks, da der Ringpuffer auf dem avr nicht größer ist.


Das macht OCR0A, aber das nutze ich nicht mehr, da ich die Ringbuffer nicht mehr nutze, ich schreibe die Samples direkt in OCR1B, geht auch.
ich rede ja auch von timer 1


Ja, dann kann ich aber die PLL nicht mehr als Timer Source verwenden.
warum?

Weiß nicht welche .h Datei mir fehlt.
die ist in der driver-lib - vermutlich nicht in arduino
Code:
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: hw_timer.c
*
* Description: hw_timer driver
*
* Modification history:
*     2014/5/1, v1.0 create this file.
*******************************************************************************/
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"

#define US_TO_RTC_TIMER_TICKS(t)          \
    ((t) ?                                   \
     (((t) > 0x35A) ?                   \
      (((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000))  :    \
      (((t) *(APB_CLK_FREQ>>4)) / 1000000)) :    \
     0)

#define FRC1_ENABLE_TIMER  BIT7
#define FRC1_AUTO_LOAD  BIT6

//TIMER PREDIVED MODE
typedef enum {
    DIVDED_BY_1 = 0,		//timer clock
    DIVDED_BY_16 = 4,	//divided by 16
    DIVDED_BY_256 = 8,	//divided by 256
} TIMER_PREDIVED_MODE;

typedef enum {			//timer interrupt mode
    TM_LEVEL_INT = 1,	// level interrupt
    TM_EDGE_INT   = 0,	//edge interrupt
} TIMER_INT_MODE;

typedef enum {
    FRC1_SOURCE = 0,
    NMI_SOURCE = 1,
} FRC1_TIMER_SOURCE_TYPE;

/******************************************************************************
* FunctionName : hw_timer_arm
* Description  : set a trigger timer delay for this timer.
* Parameters   : uint32 val :
in autoload mode
                        50 ~ 0x7fffff;  for FRC1 source.
                        100 ~ 0x7fffff;  for NMI source.
in non autoload mode:
                        10 ~ 0x7fffff;
* Returns      : NONE
*******************************************************************************/
void  hw_timer_arm(u32 val)
{
    RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val));
}

static void (* user_hw_timer_cb)(void) = NULL;
/******************************************************************************
* FunctionName : hw_timer_set_func
* Description  : set the func, when trigger timer is up.
* Parameters   : void (* user_hw_timer_cb_set)(void):
                        timer callback function,
* Returns      : NONE
*******************************************************************************/
void  hw_timer_set_func(void (* user_hw_timer_cb_set)(void))
{
    user_hw_timer_cb = user_hw_timer_cb_set;
}

static void  hw_timer_isr_cb(void)
{
    if (user_hw_timer_cb != NULL) {
        (*(user_hw_timer_cb))();
    }
}

/******************************************************************************
* FunctionName : hw_timer_init
* Description  : initilize the hardware isr timer
* Parameters   :
FRC1_TIMER_SOURCE_TYPE source_type:
                        FRC1_SOURCE,    timer use frc1 isr as isr source.
                        NMI_SOURCE,     timer use nmi isr as isr source.
u8 req:
                        0,  not autoload,
                        1,  autoload mode,
* Returns      : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR hw_timer_init(FRC1_TIMER_SOURCE_TYPE source_type, u8 req)
{
    if (req == 1) {
        RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
                      FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
    } else {
        RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
                      DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
    }

    if (source_type == NMI_SOURCE) {
        ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_isr_cb);
    } else {
        ETS_FRC_TIMER1_INTR_ATTACH(hw_timer_isr_cb, NULL);
    }

    TM1_EDGE_INT_ENABLE();
    ETS_FRC1_INTR_ENABLE();
}

//-------------------------------Test Code Below--------------------------------------
#if 0
void   hw_test_timer_cb(void)
{
    static uint16 j = 0;
    j++;

    if ((WDEV_NOW() - tick_now2) >= 1000000) {
        static u32 idx = 1;
        tick_now2 = WDEV_NOW();
        os_printf("b%u:%d\n", idx++, j);
        j = 0;
    }

    //hw_timer_arm(50);
}

void ICACHE_FLASH_ATTR user_init(void)
{
    hw_timer_init(FRC1_SOURCE, 1);
    hw_timer_set_func(hw_test_timer_cb);
    hw_timer_arm(100);
}
#endif
/*
NOTE:
1 if use nmi source, for autoload timer , the timer setting val can't be less than 100.
2 if use nmi source, this timer has highest priority, can interrupt other isr.
3 if use frc1 source, this timer can't interrupt other isr.

*/
 

xorg1990

New member
tsseh schrieb:
ich rede ja auch von timer 1
Asso, ging bist jetzt auch ohne OCR1C.

tsseh schrieb:
Weil die PLL dann für das Takten des Mikrocontrollers drauf geht.
Außerdem brauche ich keine 16 Mhz , 8Mhz tun es auch.

tsseh schrieb:
die ist in der driver-lib - vermutlich nicht in arduino
Den driver habe ich mir bereits runterganden:
https://github.com/willemwouters/ES...jects/modules/modules_1_5_0/driver/hw_timer.c

Aber es kommt dennoch:
ets_sys.h:102:23: error: 'NmiTimSetFunc' was not declared in this scope
NmiTimSetFunc(func)
^
/home/Arduino/LIchtSprechen3.0/LIchtSprechen3.0b/LIchtSprechen3.0b.ino:80:9: note: in expansion of macro 'ETS_FRC_TIMER1_NMI_INTR_ATTACH'
ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_isr_cb);





Mittlerweile habe ich das Problem gefunden warum die ADC Wandlung auf den avr schief ging.
Es lag doch am ESP und der SPI Übertragung, was auch immer da an der CLK Leitung passierte, es hat den ganzen avr gestört.

Das Kernproblem war das ich den ESP mit 160Mhz gefahren habe, da sind die ganzen Timer für den arsch (Zeiten passen nicht alles zu langsam).
Die SPI Geschwindigkeit sollte nicht unter 500 000 Hz gehen, dann tritt das Problem wider auf.

Und den transfer sollte man nicht in einer SoftwareTimer ISR machen, stattdessen Timer1 oder Timer0, habe Timer 1 genommen:
Code:
  noInterrupts();
  timer1_disable();
  timer1_isr_init();
  timer1_attachInterrupt(sendSPI);
  timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
  timer1_write((clockCyclesPerMicrosecond() / 16) * MICRODELAY);
  interrupts();
Es geht einfach nur.

Jetzt ist nur noch zu klären warum es mit 160Mhz nicht ging (ob ich da ein par defines änder muss?) und warum der HW Timer nicht compiliert .
 

tsseh

Lounge-Member
Asso, ging bist jetzt auch ohne OCR1C.
kann ich mir nicht vorstellen


Weil die PLL dann für das Takten des Mikrocontrollers drauf geht.
warum soll die "drauf gehen"?
Außerdem brauche ich keine 16 Mhz , 8Mhz tun es auch.
war auch nur ne info

Aber es kommt dennoch:
ets_sys.h:102:23: error: 'NmiTimSetFunc' was not declared in this scope
NmiTimSetFunc(func)
versuchs einfach mal mit ner vorwärtsdeklaration
Code:
void NmiTimSetFunc(void (*func)(void));
 

xorg1990

New member
tsseh schrieb:
kann ich mir nicht vorstellen
Timer/Counter1 is then set up in PWM mode, to make it act as a two-channel digital-to-analogue converter, using the values in OCR1A and OCR1B to vary the duty cycle. The frequency of the square wave is specified by OCR1C; we leave it at its default value, 255, which divides the clock by 256, giving a 250kHz square wave.
Technoblogy - Audio Sample Player

tsseh schrieb:
warum soll die "drauf gehen"?
Da man die PLL nur für eine Sache verwenden kann, genau so wie die PLL nicht einrastet wenn der MC auf unter 8Mhz läuft.

tsseh schrieb:
versuchs einfach mal mit ner vorwärtsdeklaration
Da kommt jetzt:
(.irom0.text+0xc): undefined reference to `NmiTimSetFunc(void (*)())'
/tmp/arduino_build_154877/sketch/LIchtSprechen3.0b.ino.cpp.o: In function `hw_timer_init':
/tmp/arduino_build_154877/sketch/data/hw_timer.c:74: undefined reference to `NmiTimSetFunc(void (*)())'
collect2: error: ld returned 1 exit status
 

tsseh

Lounge-Member
Die SPI Geschwindigkeit sollte nicht unter 500 000 Hz gehen, dann tritt das Problem wider auf.
das wären 2µs - glaub ich nie, dass du die hinbekommst nach allem was wir bisher mit dem timer auf dem esp gelesen und getestet haben

Code:
  timer1_write((clockCyclesPerMicrosecond() / 16) * MICRODELAY);
warum eigentlich durch 16?

Und den transfer sollte man nicht in einer SoftwareTimer ISR machen, stattdessen Timer1 oder Timer0, habe Timer 1 genommen:
ist timer1 denn kein sw-timer?
scheint so
übrigens ist timer1_isr_init:
Code:
void ICACHE_RAM_ATTR timer1_isr_init(){
    ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL);
}
und in "ets_sys.h" ist ETS_FRC_TIMER1_INTR_ATTACH definiert zu
Code:
#define ETS_FRC_TIMER1_NMI_INTR_ATTACH(func) \
	NmiTimSetFunc(func)
dazu später mehr

Da kommt jetzt:
(.irom0.text+0xc): undefined reference to `NmiTimSetFunc(void (*)())'
/tmp/arduino_build_154877/sketch/LIchtSprechen3.0b.ino.cpp.o: In function `hw_timer_init':
/tmp/arduino_build_154877/sketch/data/hw_timer.c:74: undefined reference to `NmiTimSetFunc(void (*)())'
collect2: error: ld returned 1 exit status

NmiTimSetFunc ist in libmain.a enthalten
Code:
xtensa-lx106-elf-objdump -t libmain.a | grep NmiTimSetFunc
00000078 g     F .text  00000020 NmiTimSetFunc
damit sollte das gehen.
jetzt zurück zu timer1.
dort wird timer1_isr_handler als isr übergeben, die ist definiert als
Code:
void ICACHE_RAM_ATTR timer1_isr_handler(void *para)
der linker findet bei dir NmiTimSetFunc(void (*)()) nicht, also als cb übergibst du
Code:
void ICACHE_RAM_ATTR cb()
eine funktion ohne parameter
in meinem sdk ist das in hw_timer.c auch so:
Code:
static void  hw_timer_isr_cb(void)

vermutlich nutzt arduino eine andere sdk version, wo die isr einen void pointer erwartet als parameter
du musst also vermutlich überall diesen parameter ergänzen
in dem hw_timer.c von mir dann etwa so:
Code:
...
static void (* user_hw_timer_cb)(void*) = NULL;
/******************************************************************************
* FunctionName : hw_timer_set_func
* Description  : set the func, when trigger timer is up.
* Parameters   : void (* user_hw_timer_cb_set)(void):
                        timer callback function,
* Returns      : NONE
*******************************************************************************/
void  hw_timer_set_func(void (* user_hw_timer_cb_set)(void*))
{
    user_hw_timer_cb = user_hw_timer_cb_set;
}

static void ICACHE_RAM_ATTR hw_timer_isr_cb(void*)
...

- - - Aktualisiert - - -

und der esp hat 2 hw timer

- - - Aktualisiert - - -

und du hast eine cpp datei, dann musst du die vorwärtsdeklaration noch in
Code:
extern "C" {
   
}
einschließen
 

xorg1990

New member
tsseh schrieb:
Bin der Meinung gelesen zu haben das die PLL nur funktioniert für Timner1 wenn der avr mit 8Mhz intern oder +8Mhz extern Oszillator versorgt wird.
Im Datenblatt steht davon nix.
Ist ja egal beenden wir das.


tsseh schrieb:
das wären 2µs - glaub ich nie, dass du die hinbekommst nach allem was wir bisher mit dem timer auf dem esp gelesen und getestet haben
Wer sagt das man ein SPI Transfer aller 2µs ausführen muss. Die SPI Übertragungsrate ist so hoch, aber senden tue ich ein byte aller 52µs.

tsseh schrieb:
warum eigentlich durch 16?
Frag mich was besseres.
ESP8266 microsecond delay with timer - OneTechPulse

Übrigens funktioniert Timer1 nicht wenn der esp mit 160Mhz getaktet ist. Timer0 meldet sich immer mit einem WDT Reset warum auch immer.

Die OS _Timer funktionieren mit 160Mhz genau so inakkurat wie mit 80 Mhz. Aber unter 30µs wird es kritisch dann es ist extrem inakkurat.


tsseh schrieb:
und der esp hat 2 hw timer
Wie kommt der Sinneswandel auf einmal?


tsseh schrieb:
und du hast eine cpp datei, dann musst du die vorwärtsdeklaration noch in
Habe ich.
 

tsseh

Lounge-Member
Wer sagt das man ein SPI Transfer aller 2µs ausführen muss. Die SPI Übertragungsrate ist so hoch, aber senden tue ich ein byte aller 52µs.
ob du zwischendurch auch mal pause hast oder nicht spielt ja keine rolle, du musst aber den 2µs takt überhaupt erzeugt bekommen.



prescaler 16
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);

dort steht aber auch, die genauigkeit ist ± 4µs das ist schon das aus für einen 2µs takt

Die OS _Timer funktionieren mit 160Mhz genau so inakkurat wie mit 80 Mhz. Aber unter 30µs wird es kritisch dann es ist extrem inakkurat.
die haben im sdk die untere grenze von 100µs ja sicher nicht gewürfelt
unit: microsecond, the minimum value is 0x64, the maximum value allowed to input is 0xFFFFFFF.

Wie kommt der Sinneswandel auf einmal?
https://espressif.com/sites/default/files/documentation/esp8266-technical_reference_en.pdf
Appendix 4 Timer Registers
 
Zuletzt bearbeitet:

xorg1990

New member
tsseh schrieb:
, du musst aber den 2µs takt überhaupt erzeugt bekommen.
Das macht doch die SPI Klasse, wie die das macht ist mir Wurst.
https://github.com/esp8266/Arduino/blob/master/libraries/SPI/SPI.cpp#L196

Laut Datenblatt geht spi speed bis 80Mhz:
SPI mode can be implemented via software programming. The clock frequency can reach up to
a maximum value of 80MHz.

http://www.esp8266.com/wiki/lib/exe/fetch.php?media=0a-esp8266_datasheet_en_v4.3.pdf

tsseh schrieb:
Weiß ich, erklärt aber nicht warum dort durch 16 Teilt.

tsseh schrieb:
unit: microsecond, the minimum value is 0x64, the maximum value allowed to input is 0xFFFFFFF.
Interessant.

tsseh schrieb:
Appendix 4 Timer Registers
OK.

In einem github Projekt stand geschrieben, dass die 320kBit/s wifi Bandbreite nur gehen wenn der esp mit 160Mhz getaktet ist. hast du das Quellen für??
Bei 80Mhz seien es um die 250kBit/s.

Das Verzögerungs Problem im WLAN beim senden/empfangen ist auch kein Einzelfall.

Ich glaube, die Taktfrequenz ist gar nicht der Knackpunkt. Mir kommt es
eher so vor, als ob das Modul in einem 100ms Raster arbeitet. Wenn du
viele Netzwerkpakete hintereinander sendest oder empfängst, sind
dazwischen immer Zeitabstände von ungefähr 100ms. Egal, wie groß die
Pakete sind.

https://www.mikrocontroller.net/topic/393721
 
Oben