Seite 3 von 7 ErsteErste 1234567 LetzteLetzte
Ergebnis 31 bis 45 von 97
Like Tree1Likes

Thema: für xorg1990

  1. #31
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Hi tsseh, nachdem sich alles soweit Familiär wider eingependelt hat möchte ich dich auf den aktuellen stand bringen.

    Was nicht geht:
    Das gegensprechen wird leider nichts, da die WLAN Verbindung nicht Voll-Duplex fähig ist. Ich hatte gedacht immer eine Buffer zu empfangen und einen zu senden. Im Browser habe ich immer gewartet bis ein Buffer ankommen ist, dann erst habe ich den Nächsten abgeschickt.
    Aber aus irgendwelchen gründen dauert das Umschalten zwischen empfangen und senden zu lange im ESP, bei einer Puffergroße von 128 bytes jeweils 3ms. Irgendwann läuft mir im Broser der Puffer über, selbest bei einer Samplerate von 8000Hz.

    Lasse ich das senden/empfangen weg kann ich bis zu einer SR von 44100Hz zu esp senden, allerdings mit 1sec delay.

    Es gibt im Netzt auch keine Hinweiße dadrauf wie schnell die WIFI Verbindung im esp ist und ob es ein unterschied macht zwischen Station und Access Point.

    Bei mir läuft der ESP als AP im 802.11g Protokoll was 54Mbit/s sein sollen. 802.11n funzt nur im STA modus.


    Die Übertagung vom ESP zum avr via SPI geht auch mit 44100Hz. Der avr kann PCM bis zu 48Khz wiedergeben nur die SPI Schnittstelle macht da nicht mehr mit oder einer der Prozessoren.
    44100Hz geht einwandfrei, wie gesagt mit delay.

    Die PWM Audio Qualität ist im übrigen sehr sehr gut.

    Mir fällt gerade ein das das Logitech Z-5450 Wlan Rear boxen hatte. Mal schauen ob es was gibt im Netz wie die das gelöst haben.

    Wenn du noch eine Idee hast das WLAN zu Beschleunigenen melde dich doch mal.

  2. #32
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646

    AW: für xorg1990

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Das gegensprechen wird leider nichts, da die WLAN Verbindung nicht Voll-Duplex fähig ist. Ich hatte gedacht immer eine Buffer zu empfangen und einen zu senden. Im Browser habe ich immer gewartet bis ein Buffer ankommen ist, dann erst habe ich den Nächsten abgeschickt.
    Aber aus irgendwelchen gründen dauert das Umschalten zwischen empfangen und senden zu lange im ESP, bei einer Puffergroße von 128 bytes jeweils 3ms. Irgendwann läuft mir im Broser der Puffer über, selbest bei einer Samplerate von 8000Hz.
    das verstehe ich alles nicht
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Das gegensprechen wird leider nichts, da die WLAN Verbindung nicht Voll-Duplex fähig ist. Ich hatte gedacht immer eine Buffer zu empfangen und einen zu senden. Im Browser habe ich immer gewartet bis ein Buffer ankommen ist, dann erst habe ich den Nächsten abgeschickt.
    das ist ja gerade nicht voll duplex
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Aber aus irgendwelchen gründen dauert das Umschalten zwischen empfangen und senden zu lange im ESP, bei einer Puffergroße von 128 bytes jeweils 3ms.
    welches umschalten?
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Irgendwann läuft mir im Broser der Puffer über, selbest bei einer Samplerate von 8000Hz.
    wenn ein puffer überläuft musst du den schneller leeren

  3. #33
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Zitat Zitat von tsseh
    das ist ja gerade nicht voll duplex
    Nee ist es ja auch nicht, aber da das Wlan ja bedeutend schneller ist (sein sollte) als ich Daten sende, könnte ich ja einen Buffer senden im ESP verarbeiten und danach vom ESP zurück zum Browser senden. So als wenn es den eindruck von voll-duplex vermittelt.

    Angenommen ich sende in der Sekunde 8000bytes zum esp und das wlan geht bis 54Mbit/s dann sind die 8000bytes ja im nu durch, es sollte genügend Zeit sein um 8000bytes auch wider zum Browser zurück zu senden. Der esp läuft wahlweise mit 80 oder 160Mhz. Alles was das zwischen ist, ist eine Schleife und der SPI Transfer. Selbst wenn ich die schleife und den SPi Transfer weglassen ist der ESP nicht in der Lage 8000bytes zu empfange und anschließend zu senden.


    Im Browser vergehen zwichen send() Event und onmessage event immer 3ms. Selbst wenn ich die 8000bytes in 128byte große cuncks unterteile.

    Meine Vermutung ist, das das "umschalten" zwischen empfangen und senden zu lange dauert. Keine Ahnung wie das im ESP funktioniert WLAN ist OFDM Moduliert und irgendwo muss noch ein Tuner sein. Die OFDM Modulation ist sehr sehr sehr Rechen aufwendig wenn das nicht in Hardware gelöst wird das ist das das Problem.

    Digitalradio, DVB-T und Satellit Übertagung ist alles OFDM:
    https://www.csie.ntu.edu.tw/~hsinmu/...l/ofdm_new.pdf
    Geändert von xorg1990 (29-05-2017 um 23:34 Uhr)

  4. #34
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646

    AW: für xorg1990

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Im Browser vergehen zwichen send() Event und onmessage event immer 3ms. Selbst wenn ich die 8000bytes in 128byte große cuncks unterteile.
    find ich jetzt sehr wenig. die verbindung muss ja auch erst aufgebaut werden oder geht das über eine stehende verbindung? websocket? aber selbst wenn, find ich 3ms wahnsinnig schnell. onmessage läuft ja in einem anderen js-abarbeitungspfad als send. da hätte ich locker mit 20-30ms gerechnet.

  5. #35
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Naja wenn du die 8000byte in rund 64 a 128bytes große Teile unterteilst, hast du 192ms Verzögerung.

    Außerdem ist das mit den 3 ms etwas geflunkert, weil ab und zu mal verausgabt sich der esp total dann hast man mal 700 oder 600ms delay.

    Ich möchte mal prüfen ob auch so ist wenn der esp als Station läuft. Nicht das er als AP noch andere dinge zu elendigen hat wie z.b Kanäle ausortieren oder eine art Fehlerkorrekturverfahren, die ich nicht brauche da ja das TCP Protokoll sowas schon beinhaltet.

    Ach ja und ich verwende eine Werbsocket Verbindung:
    https://github.com/Links2004/arduinoWebSockets

    - - - Aktualisiert - - -

    Schau mal:
    http://zonerobotics.com/throughput-testing-of-esp8266-module-size-matters/
    oder
    http://bbs.espressif.com/viewtopic.php?t=2187

    Klärt aber nicht warum das senden/empfangen toggeln so lange dauert.

  6. #36
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Naja wenn du die 8000byte in rund 64 a 128bytes große Teile unterteilst, hast du 192ms Verzögerung.
    wie gesagt, 3ms zw. 2 events im browser finde ich schnell (für js verhältnisse)
    auf dauer wirst du den browser das (vermutlich) auch nicht abverlangen können

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Außerdem ist das mit den 3 ms etwas geflunkert, weil ab und zu mal verausgabt sich der esp total dann hast man mal 700 oder 600ms delay.
    600 sind zuviel, das dürfte dann tatsächlich am esp liegen, der dann mit anderen dingen beschäftigt sein wird

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Ich möchte mal prüfen ob auch so ist wenn der esp als Station läuft. Nicht das er als AP noch andere dinge zu elendigen hat wie z.b Kanäle ausortieren oder eine art Fehlerkorrekturverfahren, die ich nicht brauche da ja das TCP Protokoll sowas schon beinhaltet.
    selbst wenn, das sind alles keine 600ms. außerdem werden sie genau das machen was notwendig ist


    das ist aber wieder was anderes.
    1. dass du die 54 Mbit nicht als reine nutzdatenrate hast ist ja klar
    2. mit der antenne wirst du überhaupt nicht in die nähe der 54 Mbit kommen
    3. ist das die übertragung über das serielle at-protokoll. du sendest alles an den esp über die serielle schnittstelle(die hatten eine baudrate von 400k glaube ich, schneller geht es damit schon mal nicht). den at-befehl musst du dann noch parsen. und dann erst wird das über wlan gesendet. die nächste frage ist, wieviel daten senden sie immer. auf 2k blöcke muss das sowieso aufgeteilt werden, sprich das ganze prozedere muss für mindestens jeden 2k block laufen. nehmen sie kleinere blöcke, dann entsprechend öfter.


    Zitat Zitat von xorg1990 Beitrag anzeigen
    Klärt aber nicht warum das senden/empfangen toggeln so lange dauert.
    genau!
    von welchem fall sprechen wir hier? die 3ms sind erklärbar, die 600ms nicht

    - - - Aktualisiert - - -

    Zitat Zitat von tsseh Beitrag anzeigen
    von welchem fall sprechen wir hier? die 3ms sind erklärbar, die 600ms nicht
    vielleicht doch nicht unbedingt, hier mal ein testUnbenannt.png
    von regelmäßigen ausrutschern mal abgesehen um die 0-1 ms bei lokalem php-websocket-server

  7. #37
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Habe heute auch noch mal getestet es dauert nämlich bedeutend länger. Habe mit diesmal mit den ESP 03 gemessen und mit SPi Übertagung an den AVR. so wie es ja am Ende sein soll.

    Zwichen request und responce liegen total willkürliche Zeiten:
    80Mhz...8kHz.jpg

    gemessen wurde mit performance.now();

    Habe alle WLAN Protokolle druck CPU Frequenz 160/80Mhz Station/AP... keine Änderung.

    Alle 3ms wird ein onmessage event gefeuert wenn ich vom esp zum browser sende only.

    Ebenfalls festgestellt habe ich, dass gar kein onmessege event gefeuert wird wen der zu sendende Puffer großer ist als 1024bytes.
    Selbst wenn ich via undef das WEBSOCKETS_USE_BIG_MEM herausnehme https://github.com/Links2004/arduino...bSockets.h#L50

    Andersrum vom Browser zum esp kann ich bis 16384 und mehr bytes.

    Also half duplex only oder hast du noch eine idee?? AJAX vielleicht?

  8. #38
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Zwichen request und responce liegen total willkürliche Zeiten:
    naja, ganz so willkürliche sind die ja nicht, mit 100ms würde ich aber rechnen

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Alle 3ms wird ein onmessage event gefeuert wenn ich vom esp zum browser sende only.
    wenn du zusätzlich was machst, ist es ja klar, dass du für kommunikation und verarbeitung von daten über wlan weniger zeit hast

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Ebenfalls festgestellt habe ich, dass gar kein onmessege event gefeuert wird wen der zu sendende Puffer großer ist als 1024bytes.
    ohne jetzt wirklich nachgesehen zu haben sollten es 15*1024 für den empfangspuffer sein und beim senden ohne limitierung, aber selbst mit 1024 und 100ms sollte es doch gerade so gehen deine 8000 byte zu übertragen. zur sicherheit solltest du doppelt soviel puffern, falls die 100ms mal mehrfach überschritten werden.

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Selbst wenn ich via undef das WEBSOCKETS_USE_BIG_MEM herausnehme https://github.com/Links2004/arduino...bSockets.h#L50
    das hat damit nichts zu tun, das sorgt nur dafür das die daten nicht gestückelt werden, wenn sie in ein tcp-paket passen

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Also half duplex only oder hast du noch eine idee?? AJAX vielleicht?
    versuchs mit ajax, prinzipiell sollte das eher langsammer sein

  9. #39
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Zitat Zitat von tsseh
    ohne jetzt wirklich nachgesehen zu haben sollten es 15*1024 für den empfangspuffer sein und beim senden ohne limitierung, aber selbst mit 1024 und 100ms sollte es doch gerade so gehen deine 8000 byte zu übertragen. zur sicherheit solltest du doppelt soviel puffern, falls die 100ms mal mehrfach überschritten werden.
    Nee 100ms ist zu langsam selbst mit 6000byte läuft der Puffer über. Der Puffer hat schon die 4 Fache größe.

    Du Musst ja auch damit rechen das das Schreiben in den Puffer an den Event vom ScriptProcessor hängt wenn die Samplerate im Browser 44100Hz ist und die Puffergröße des SP 16384, dann schreibe ich aller 1/44100*16384 = 0,371519274 Sekunden rund 5000 bytes in den Ringpuffer.
    5000byte daher weil down gesampled auf 8000Hz.

    Oder wie hast du gedacht?

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

    Aber avr hin oder her selbst wenn ich keine SPI Übertagung mache und nur die Websocket Klasse auf den ESP läuft geht es nicht!
    Selbst wenn ich 1024byte große chunks mache.

    Zitat Zitat von tsseh
    versuchs mit ajax, prinzipiell sollte das eher langsammer sein
    Ja eigentlich kann es nicht schneller sein. Wenn es aber geht spare ich immerhin eine Klasse ein.
    Einfach ausprobieren.
    Geändert von xorg1990 (01-06-2017 um 23:37 Uhr)

  10. #40
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Du Musst ja auch damit rechen das das Schreiben in den Puffer an den Event vom ScriptProcessor hängt wenn die Samplerate im Browser 44100Hz ist und die Puffergröße des SP 16384, dann schreibe ich aller 1/44100*16384 = 0,371519274 Sekunden
    das sind aber fast 400 ms

    Zitat Zitat von xorg1990 Beitrag anzeigen
    rund 5000 bytes in den Ringpuffer.
    3000

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Oder wie hast du gedacht?
    ich habe gedacht, daß 3000 byte aller 400ms drinn sein sollten

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Senden und Empfangen tue ich aber jeweils nur 128byte große chunks, da der Ringpuffer auf dem avr nicht größer ist.
    ach daran liegts? ist ja aber für die übertragung zum esp über wlan erst mal egal. wenn du die 3000 byte immer im block zum esp sendest und dann diesen block auf dem esp nochmal in 128 byte blöcke unterteilst und zum avr sendest sollte das doch gehen. hast halt ne halbe sekunde verzögerung drinn

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Aber avr hin oder her selbst wenn ich keine SPI Übertagung mache und nur die Websocket Klasse auf den ESP läuft geht es nicht!
    Selbst wenn ich 1024byte große chunks mache.
    weil? wie sind denn die zeiten? mit 3000, 1024 und 128byte? die ~100 ms waren für die 128byte blöcke? wächst das in etwa linear an wenn du 1024 byte blöcke nimmst? ich hätte jetzt erwartet dass das nicht passiert, wenn du für 1024 byte blöcke dann aber fast ne sekunde brauchst liegt es wohl wirklich an der wlan übertragungsrate, das glaube ich aber nicht wirklich.

  11. #41
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Zitat Zitat von tsseh
    wenn du die 3000 byte immer im block zum esp sendest und dann diesen block auf dem esp nochmal in 128 byte blöcke unterteilst und zum avr sendest sollte das doch gehen. hast halt ne halbe sekunde Verzögerung drin
    Nee leider geht das auch nicht, da selbst wenn ich einen 3000byte großen Puffer zum esp sende und exakt diesen wider zurücksende dauert es zu lange. im Browser läuft der puffer über. Der Code ist denkbar einfach.
    Außerdem kommt kein onmessage event wenn der zu sendete Puffer größer ist als 1024byte.

    Code:
    var bufferSize = 16384;
    var chunkSize = 128;
    		var sendTime = 0;
    		let canTransmit = false;
    		let Uint8Buf = new Uint8Array(bufferSize*4);
    var bufferMask = Uint8Buf.length-1;
    
    	resampler.resampleOutput = function(output){
    			if(connected){
    			 for (let i=0;i<output.length;i++){
    			 	let next = ((w_ptr + 1) & bufferMask);
    			 	if (r_ptr == next){
    					console.log("buffer voll");
    			 		break;
    			 	}
    			 	let filterSample = FirFilter.pushSample(output[i]);
    		        let s = Math.max(-1, Math.min(1, filterSample));
    		        s = parseInt(s*127+128);
    		        Uint8Buf[w_ptr] = s;
    		        w_ptr=next;
    		        if(next == chunkSize && canTransmit == false){
    		        	canTransmit == true;
    		        	transmit();
    		        }
    			}
    		}
    	}
    
    function transmit(){
    		var subBuffer = Uint8Buf.subarray(r_ptr,r_ptr+chunkSize);
    			 if (r_ptr == w_ptr){
    			 	console.log("buffer leer");
    			 	return;
    			 }
    			r_ptr = (r_ptr+chunkSize) & bufferMask;
    			sendTime = performance.now();
    			WsConnection.send(subBuffer);
    	}
    
    	function handleOnmessage(e){
    			var rtime = performance.now() - sendTime;
    			console.log(rtime);
    			transmit();
    			//console.log(e.data.byteLength);
    		}
    aufm esp:
    Code:
    void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
        switch(type) {
            case WStype_DISCONNECTED:
               Serial.println("Disconnected");
                break;
            case WStype_CONNECTED:
                {
                    IPAddress ip = webSocket.remoteIP(num);
                }
                break;
            case WStype_BIN:
                // send message to client
                webSocket.sendBIN(num, payload, length);
                break;
        }
    
    }
    Wenn diese Bedingung erfüllt ist, wird der Prozess in Gang gebracht:
    next == chunckSize && canTransmit == false
    Irgendwann kommt dann console.log("buffer voll");

    Zitat Zitat von tsseh
    die ~100 ms waren für die 128byte blöcke? wächst das in etwa linear an wenn du 1024 byte blöcke nimmst?
    Die ~100ms sind für die 128 blöcke -richtig.
    Ja da wächst was linear an und zwar das senden vom esp zum Browser hin bei 1024byte großen Blöcken kommen die Events total unregelmäßig. Bis sogar die Socket Verbindung geschlossen wird "invalid frame..irgendwas". Bei 128-512 großen Blöcken kommt der Message event viel regelmäßiger, keine ausfälle.

    Da habe ich jetzt festgestellt, da ich nun eine Sende /Empfangs Umschaltung mache.

    Ajax habe ich getestet und ist ~50ms langsamer aber die callbacks kommen viel gleichmäßiger nicht so wirr wie beim Websocket.

  12. #42
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646
    Zitat Zitat von xorg1990 Beitrag anzeigen
    Nee leider geht das auch nicht, da selbst wenn ich einen 3000byte großen Puffer zum esp sende und exakt diesen wider zurücksende dauert es zu lange. im Browser läuft der puffer über.
    wenn ein puffer im Browser voll läuft, kann das doch fast nicht am esp liegen. der browser sendet die daten doch nur zum esp und gut. klar, tcp erwartet eine rückmeldung, darauf wartet allerdings das 2. send nicht. gut, irgendwann ist auch der puffer des ip-stacks voll. dann sollte aber nicht dein puffer überlaufen, sondern das send des websockets eine fehlermeldung bringen.
    um das mal auszutesten kannst du mal versuchen die puffer des systems zu vergrößern, dann sollte es länger laufen.
    unter windows ist das der registry eintrag [HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet \Services \Afd \Parameters]
    nicht vergessen das nach dem test wieder in den originalzustand zu bringen

    - - - Aktualisiert - - -

    jetzt hab ich mir mal deinen code angesehen, du machst das transmit() in abhängigkeit von handleOnmessage
    das ist nur zum testen? warum rufst du transmit() nicht immer auf, wenn was zu senden da ist?

  13. #43
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Zitat Zitat von tsseh
    jetzt hab ich mir mal deinen code angesehen, du machst das transmit() in abhängigkeit von handleOnmessage
    das ist nur zum testen? warum rufst du transmit() nicht immer auf, wenn was zu senden da ist?
    Nein, da ist nicht nur zum testen. So war der Plan. Wie gesagt ich hätte gerne eine Voll-Duplex Lösung und bin davon ausgegangen das das Senden/Empfangen so schnell geht, das es zu keine nennenswerten delay kommt. Ja, wie du seihst ~100ms delay pro onmessage.

    Sende ich immer wenn Daten da sind, bräuchte ich eine Sende-Empfangs Umschaltung. Sprich einen Button den man drückt wenn wenn man was senden Möchte. Der ESP muss halt drauf reagieren.


    So mache ich's nun auch, weil ich bin mit meinem Latein am ende.
    Festgestellt habe ich bis jetzt nur, das ab 32000byte/sec es zu 1sec delay kommt zwischen Sound Input und der Ausgabe.

    Und beim avr beeinflusst der ADC die SPI Übertragung, da bin ich gerade dran am Eruieren warum das so ist.

    - - - Aktualisiert - - -

    Zitat Zitat von xorg1990
    Und beim avr beeinflusst der ADC die SPI Übertragung, da bin ich gerade dran am Eruieren warum das so ist.
    Ich komme nicht dahinter, immer wenn ich eine adc Wandlung mache ADCSRA |= (1 << ADSC); kommt am USIDR müll raus.

    Sprich ich sende vom esp zum avr nur Nullen, ergo sollte die LED aus sein. Das haut auch hin, nur immer wenn ich eine ADC Wandlung vornehme Free Running oder Anders blinkert die LED Unkontrolliert, es knattert und knarzt wie damals beim ESP.

    Code:
    #define F_CPU 8000000UL
    
    
    #define bufferSize 128
    #define BUFFER_MASK (bufferSize-1)
    /*
      Pinmodes
      PB0 MOSI
      PB1 MISO
      PB2 Clock
      PB3 ADC Input
      PB4 PWM Out
    */
    static struct adc_FIFO {//ringBuffer als struct für pcm saples
      byte data[bufferSize];
      volatile byte read_ptr; // zeigt auf das Feld mit dem ältesten Inhalt
      volatile byte write_ptr; // zeigt immer auf leeres Feld
    } adc_buffer = {{}, 0, 0};
    
    static struct pcm_samples_buffer {//ringBuffer als struct für pcm saples
      byte data[bufferSize];
      volatile byte read_ptr; // zeigt auf das Feld mit dem ältesten Inhalt
      volatile byte write_ptr; // zeigt immer auf leeres Feld
    } pcm_buffer = {{}, 0, 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 19230Hz 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
    
        //ADC settings 8bit value
      ADMUX =   3 | //channel 3
                (1 << ADLAR) |     // left shift result
                (0 << REFS2) |     // Sets ref. voltage to internal 1.1V, bit 2
                (1 << REFS1) |     // Sets ref. voltage to internal 1.1V, bit 1
                (0 << REFS0) ;     // Sets ref. voltage to internal 1.1V, bit 0
    
      ADCSRA =
        (1 << ADEN)  |     // Enable ADC at 19230 Hz Samplerate
        (1 << ADPS2) |     // set prescaler to 32, bit 2
        (0 << ADPS1) |     // set prescaler to 32, bit 1
        (1 << ADPS0) |      // set prescaler to 32, bit 0
        (1 << ADIE); //enabel adc isr
        
    //SPI settings 
      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
    
    
      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 38kHz
      byte adcValue = ADCH;
      byte next = ((adc_buffer.write_ptr + 1) & BUFFER_MASK);
      if (adc_buffer.read_ptr != next) {
        adc_buffer.data[adc_buffer.write_ptr] = adcValue;
        //buffer.data[buffer.write_ptr & BUFFER_MASK] = byte;
        adc_buffer.write_ptr = next;
      }
      ADCSRA |= (1 << ADSC);        // Start the next conversion
    }
    
    
    // Sample interrupt 19khz
    ISR(TIMER0_COMPA_vect) {
      if (pcm_buffer.read_ptr != pcm_buffer.write_ptr) {
        byte sample  =  pcm_buffer.data[pcm_buffer.read_ptr];
        pcm_buffer.data[pcm_buffer.read_ptr] = 0;
        OCR1B = sample;
        pcm_buffer.read_ptr = (pcm_buffer.read_ptr + 1) & BUFFER_MASK;
      }
    }
    
    ISR(USI_OVF_vect) {
      byte incommingByte = 0;
      // Wait for complete byte to arrive
      while ((USISR & (1 << USIOIF)) == 0) {
      }
      // Clear counter overflow flag so next byte can begin arriving
      // While we're processing this one
      USISR = (1 << USIOIF);
      incommingByte = USIDR;
      byte next = ((pcm_buffer.write_ptr + 1) & BUFFER_MASK);
      if (pcm_buffer.read_ptr != next) {
        pcm_buffer.data[pcm_buffer.write_ptr] = incommingByte;
        pcm_buffer.write_ptr = next;
      } else {
        pcm_buffer.data[pcm_buffer.write_ptr] = 0;
      }
      if (adc_buffer.read_ptr !=   adc_buffer.write_ptr) {
        byte adcValue =  adc_buffer.data[adc_buffer.read_ptr];
        adc_buffer.data[adc_buffer.read_ptr] = 0;
        USIDR = adcValue; // Put data in USI data register.
        adc_buffer.read_ptr = (adc_buffer.read_ptr + 1) & BUFFER_MASK;
      } else {
        USIDR = 0;// Put data in USI data register.
      }
    }
    
    void loop() {
    }
    Was auf jeden Fall funzt ist die Übertagung vom Browser zum ESP und dann zum avr, der daraus PWM Audio macht. Nur um da erstmal ein Strich drunter zu machen.
    Geändert von xorg1990 (06-06-2017 um 23:36 Uhr)

  14. #44
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.646

    AW: für xorg1990

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Nein, da ist nicht nur zum testen. So war der Plan. Wie gesagt ich hätte gerne eine Voll-Duplex Lösung und bin davon ausgegangen das das Senden/Empfangen so schnell geht, das es zu keine nennenswerten delay kommt.
    und warum musst du dann warten mit senden, bis du wieder was empfangen hast?

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Sende ich immer wenn Daten da sind, bräuchte ich eine Sende-Empfangs Umschaltung. Sprich einen Button den man drückt wenn wenn man was senden Möchte.
    nee, jedenfalls hat das nichts mit senden wenn daten da sind zu tun, ob du das generell brauchst, keine ahnung

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Der ESP muss halt drauf reagieren.
    dafür gibt es ja die events

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Und beim avr beeinflusst der ADC die SPI Übertragung, da bin ich gerade dran am Eruieren warum das so ist.
    der interrupt des ADC wird den des SPI unterbrechen/verzögern

    - - - Aktualisiert - - -

    Zitat Zitat von xorg1990 Beitrag anzeigen
    // Enable ADC at 19230 Hz Samplerate
    wie kommst du auf 19230 Hz?
    Zitat Zitat von xorg1990 Beitrag anzeigen
    ISR(ADC_vect) { // interuppt each 38kHz
    jetzt 38kHz? was hast du für eine cpu frequenz? 16MHz? dann wäre deine adc clock mit 500kHz aber zu schnell

    Zitat Zitat von xorg1990 Beitrag anzeigen
    while ((USISR & (1 << USIOIF)) == 0) {
    }
    das sollte nicht notwendig sein

    Zitat Zitat von xorg1990 Beitrag anzeigen
    Ich komme nicht dahinter, immer wenn ich eine adc Wandlung mache ADCSRA |= (1 << ADSC); kommt am USIDR müll raus.
    das sehe ich so auch erst mal nicht. die isr's "sehen" nicht nach langer laufzeit "aus". die tacktgeber der isr's sind auch unabhängig.
    1) müsste man mal die echte laufzeit der jeweiligen isr's wissen. also entweder den asm-code ansehen und die zyklen ausrechnen (hier jeweils am befehl ganz am ende http://www.atmel.com/webdoc/avrassem...tion_list.html) oder am anfang und ende der isr jeweils einen gpio toggeln und dann messen
    2) müsste man mal die prioritäten der isr's raussuchen um auszuschließen das einer verhungert weil die beiden höherprioren sich immer abwechseln (dazu müsste aber die laufzeit aus 1 auch schon zu groß sein)
    am besten wäre du könntest in jeder isr einen anderen gpio toggeln und diesen mit 3 kanälen aufzeichnen.
    Geändert von tsseh (07-06-2017 um 15:08 Uhr)

  15. #45
    Avatar von xorg1990
    xorg1990 ist offline König
    registriert
    20-12-2013
    Beiträge
    851

    AW: für xorg1990

    Zitat Zitat von tsseh
    und warum musst du dann warten mit senden, bis du wieder was empfangen hast?
    Wo warte ich denn?? Also wo warte ich absichtlich?? Woher die ~100ms delay kommen ist ja die große Frage.


    Zitat Zitat von tsseh
    der interrupt des ADC wird den des SPI unterbrechen/verzögern
    Möglich.

    Zitat Zitat von tsseh
    wie kommst du auf 19230 Hz?
    8Mhz CPU Clock
    ADC Vorteiler 32

    8 000 000/32=250000Hz
    250000/13=19230Hz SampleRate.

    Durch 13 deswegen, weil eine Wandlung 13 Takte braucht.

    Zitat Zitat von tsseh
    jetzt 38kHz? was hast du für eine cpu frequenz? 16MHz? dann wäre deine adc clock mit 500kHz aber zu schnell
    Ignoriere das! Der Kommentar stammt noch aus versuch 1.

    Zitat Zitat von tsseh
    das sollte nicht notwendig sein
    Da wäre ich mir nicht so sicher. Wenn man das bei einer ADC ISR macht hast du da eine Endlosschleife, weil die Wandlung bereits abgeschlossen ist wenn die ISR gefeuert wird. Bei der usi ISR warte ich bis ein komplettes Byte übertragen wurde, da SPI immer nur bit's überträgt.

    Man kann es ja mal weglassen.

    Zitat Zitat von tsseh
    das sehe ich so auch erst mal nicht. die isr's "sehen" nicht nach langer laufzeit "aus". die tacktgeber der isr's sind auch unabhängig.
    1) müsste man mal die echte laufzeit der jeweiligen isr's wissen. also entweder den asm-code ansehen und die zyklen ausrechnen (hier jeweils am befehl ganz am ende Atmel AVR 8-bit and 32-bit Microcontrollers) oder am anfang und ende der isr jeweils einen gpio toggeln und dann messen
    2) müsste man mal die prioritäten der isr's raussuchen um auszuschließen das einer verhungert weil die beiden höherprioren sich immer abwechseln (dazu müsste aber die laufzeit aus 1 auch schon zu groß sein)
    am besten wäre du könntest in jeder isr einen anderen gpio toggeln und diesen mit 3 kanälen aufzeichnen.
    Glaube nicht das an den ISR's liegt.
    Den USI_OVF_vect feuert der ESP, da der Master ist.

    Und selbst wenn ich in der Haupt schleife eine Einzelmessung mache, also ISR(ADC_vect) komplett weg lasse habe ich immer noch das Problem.

    - - - Aktualisiert - - -

    ok, das while ((USISR & (1 << USIOIF)) == 0) { kann tatsächlich weggelassen werden.

    aber die LED an PB4 hat dennoch ein Eigenleben, Problem nicht behoben.

    Die ISR'S von adc und vom usi habe ich mal ausgeschalten und dafür das in die loop geschrieben:

    Code:
    void loop() {
       ADCSRA |= (1 << ADSC);        // Start the next conversion
        while (ADCSRA & (1 << ADSC) )         // auf Abschluss der Konvertierung warten
      {
      }
      byte adcValue = ADCH;
      byte next_a = ((adc_buffer.write_ptr + 1) & BUFFER_MASK);
      if (adc_buffer.read_ptr != next_a) {
        adc_buffer.data[adc_buffer.write_ptr] = adcValue;
        //buffer.data[buffer.write_ptr & BUFFER_MASK] = byte;
        adc_buffer.write_ptr = next_a;
      }
      
       byte incommingByte = 0;
      // Wait for complete byte to arrive
      while ((USISR & (1 << USIOIF)) == 0) {}
      // Clear counter overflow flag so next byte can begin arriving
      // While we're processing this one
      USISR = (1 << USIOIF);
      incommingByte = USIDR;
      byte next = ((pcm_buffer.write_ptr + 1) & BUFFER_MASK);
      if (pcm_buffer.read_ptr != next) {
        pcm_buffer.data[pcm_buffer.write_ptr] = incommingByte;
        pcm_buffer.write_ptr = next;
      } else {
        pcm_buffer.data[pcm_buffer.write_ptr] = 0;
      }
      if (adc_buffer.read_ptr !=   adc_buffer.write_ptr) {
        byte adcValue =  adc_buffer.data[adc_buffer.read_ptr];
        adc_buffer.data[adc_buffer.read_ptr] = 0;
        USIDR = adcValue; // Put data in USI data register.
        adc_buffer.read_ptr = (adc_buffer.read_ptr + 1) & BUFFER_MASK;
      } else {
        USIDR = 0;// Put data in USI data register.
      }
    }
    Keine Änderung.

    Nochmal zum Verständnis, die LED hängt an PB4, und der Analog Pin ist PB3. Die SPI Pins sind die wie im Datenblatt.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •