Thema: für xorg1990
-
04-07-2017, 08:10 #61
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
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
By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution.
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
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.
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.
unit: microsecond, the minimum value is 0x64, the maximum value allowed to input is 0xFFFFFFF.
APIs in hw_timer.c can not be called when PWM APIs are in use, because they all use the same hardware timer.
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.
Code:hw_timer_init(FRC1_SOURCE, 1); hw_timer_set_func(hw_timer_cb); hw_timer_arm(50);
The hardware timer callback function must NOT be defined with ICACHE_FLASH_ATTR.
-
04-07-2017, 12:47 #62
AW: für xorg1990
Zitat von tsshe
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.
Zitat von tsseh
Zitat von tsseh
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));
Zitat von tsseh
Zitat von tsseh
-
04-07-2017, 13:43 #63
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
AW: für xorg1990
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.
ok, dann nimm die 16
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
kann ich mir vorstellen
warum mal 2? durch 2
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
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
???? 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.
-
04-07-2017, 21:26 #64
AW: für xorg1990
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
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.
-
05-07-2017, 07:26 #65
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
AW: für xorg1990
ich hab keine gefunden
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
ja, ich dachte das ist das ziel, wiel schon ohne dopplung der wotchdog kommt
ja
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
mal probiert?Geändert von tsseh (05-07-2017 um 09:27 Uhr)
-
05-07-2017, 19:47 #66
AW: für xorg1990
Zitat von tsseh
Zitat von tsseh
Homepage Uwe Freese - Leiser Rechner
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
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.
Zitat von tsseh
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.
-
06-07-2017, 11:08 #67
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
AW: für xorg1990
das ist aber für arduino
ja und? die frage ist ja was du mit dem quarz an einem gpio willst?
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.
das wlan alleine ist erst mal schnell genug wie mein test gezeigt hat.
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 - - -
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 - - -
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.
Code:PLLCSR |= (1 << PLLE); // PLL enable while ((PLLCSR & (1 << PLOCK)) == 0x00){} // warten auf sync PLLCSR |= (1 << PCKE); // Enable asynchronous mode
-
06-07-2017, 20:11 #68
AW: für xorg1990
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
Von den Fuses her, habe ich nur die von der Taktung gesetzt.
Zitat von tsseh
Die musste ganz an das Ende von den USI Gedöns. ich vergaß.
Zitat von tsseh
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); */ }
Zitat von xorg1990
Geändert von xorg1990 (06-07-2017 um 20:09 Uhr)
-
06-07-2017, 21:04 #69
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
AW: für xorg1990
dass ich mit dem esp bisher nur mit dem sdk gearbeitet habe
naja
ich auch
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
das sollte egal sein
weil OCR1C festlegt bis wohin gezählt wird
der teiler, ist der enabled läuft die cpu mit 1 MHz
-
07-07-2017, 09:36 #70
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
AW: für xorg1990
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.
-
07-07-2017, 22:53 #71
AW: für xorg1990
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
Zitat von tsseh
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/b...sp8266_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.
-
08-07-2017, 00:17 #72
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
ich rede ja auch von timer 1
warum?
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. */
-
09-07-2017, 08:57 #73
AW: für xorg1990
Zitat von tsseh
Zitat von tsseh
Außerdem brauche ich keine 16 Mhz , 8Mhz tun es auch.
Zitat von tsseh
https://github.com/willemwouters/ESP...ver/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();
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 .
-
09-07-2017, 09:16 #74
Foren-Gott
- registriert
- 19-05-2008
- Beiträge
- 5.630
-
09-07-2017, 12:44 #75
AW: für xorg1990
Zitat von tsseh
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.
Zitat von tsseh
Zitat von tsseh
(.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
Lesezeichen