DOOM Watch auf ESP32. Teil 1

Nachdem ich die Entwicklung mit vorgefertigten ESP32-Modulen ausprobiert hatte, wollte ich etwas Kleines und Natives machen. Ich beschloss, eine Uhr zu machen. Zuerst dachte ich an den ESP32-PICO-D4 . Da das Programm nur 4 MB Flash enthält, habe ich mich für eine Vollversion mit einer Erweiterung von bis zu 16 MB Flash und 8 MB SRAM entschieden. Unabhängig von der Uhr können Sie das erste Doom ausführen. Im Allgemeinen war das alles voll!



Was wurde noch nicht getan oder muss verbessert werden:

  1. Batterieanzeige
  2. Auf Schottky-Diode implementierte Ladungssperrschaltung
  3. Die Antenne befindet sich nicht sehr gut auf einer anderen Schicht von ESP32

Kein Tutorial!



Durch Anzeige




Ich habe ein Farbdisplay auf dem ST7789-Controller mit einer Auflösung von 240 x 240 angewendet. Es ist ziemlich kompakt und billig. Im Netzwerk werden immer mehr Treiber und Ports angezeigt. Zum Beispiel gibt es einen Anschluss für LittlevGL , aber auf diesem Display befindet sich keine Schubkarre. Ich denke, es kann gekauft und geklebt werden. Vielleicht hat jemand Erfahrung? Share.

Ich habe ein Board auf ST7789 entwickelt und es wurde ohne Probleme gestartet.



LittlevGL esp32


Durch Füllen von Programmen und Debuggen


Ich habe den USB-TO-UART BRIDGE- Konverter CP2102 verwendet . Erstens ist es kompakt und zweitens ist der Anschlussplan sehr einfach und es werden fast keine zusätzlichen Teile benötigt.
Option 2: Ein 4,7-μF-Kondensator kann hinzugefügt werden, wenn andere Geräte über den On-Chip-Regler mit Strom versorgt werden.
Wenn Sie REGIN und VBUS an ein USB 5V-Netzteil anschließen, benötigen Sie nur einen Nebenschlusskondensator am Eingang. Obwohl ich denke, dass es ohne es funktionieren kann. VDD auf einem Chip ist in diesem Fall der Ausweg! Ich habe einen Fehler gemacht und ihn an den 3,3-V-Stromkreis angeschlossen und konnte nicht verstehen, warum ich 4,65 V an der Stromversorgung habe ?!

Der Link in der folgenden Dokumentation enthält Optionen zum Anschließen an eine 3,3-V-Stromversorgung. Ich denke jedoch, dass CP2102 absolut nicht mit Strom versorgt werden muss, wenn das Gerät nicht hochgeladen oder debuggt werden muss



Laden des Modulo-Akkus


Der Widerstand am LTC4054 stellt den Ladestrom ein:



Ernährung


Stromversorgung über 3,7-V-Batterien mit Stabilisator HT7833. Ausgangsstrom 500mA. Es hat einen kleinen Spannungsabfall von ~ 300 mV. LD1117-3.3 hat "ein bisschen" mehr.

Ein Hinweis zu den Schlussfolgerungen von VDD_SDIO. Dieser Pin-Stromversorgungsausgang beträgt 1,8 V oder 3,3 V, abhängig vom Status des IO12-Mikrocontrollers beim Start . 3,3 V GPIO12 ist 0 (Standard)
VDD_SDIO works as the power supply for the related IO, and also for an external device.

When VDD_SDIO operates at 1.8 V, it can be generated from ESP32’s internal LDO. The maximum currentthis LDO can offer is 40 mA, and the output voltage range is 1.65 V~2.0 V.

When the VDD_SDIO outputs 1.8 V, the value of GPIO12 should be set to 1 when the chip boots and it is recommended that users add a2 kΩ ground resistor and a 4.7 mF filter capacitor close to VDD_SDIO.

When VDD_SDIO operates at 3.3 V, it is driven directly by VDD3P3_RTC through a 6Ωresistor, therefore,there will be some voltage drop from VDD3P3_RTC.

When the VDD_SDIO outputs 3.3 V, the value of GPIO12 is 0 (default) when the chip boots and it is recommended that users add a 1mF capacitor close to VDD_SDIO

Dies ist sehr praktisch, wenn Sie 1,8 V Blitz haben. In meinem Fall habe ich diese Schlussfolgerung gezogen und meinen 3V3-Blitz und mein PSRAM an das allgemeine Netzteil angeschlossen.

Einige ESP32-Module verwenden VDD_SDIO, daher kann ich beim Start nichts an die Peripheriegeräte von IO12 hängen. Sie können beispielsweise eine Schaltfläche aufhängen. In einer meiner Lösungen habe ich ein SPI-Bein an IO12 gehängt und das Modul wurde nicht gestartet. Anscheinend hat IO12 eine Einheit von diesem SPI-Port bekommen, aber ich brauchte 0 oder umgekehrt. Dies muss berücksichtigt werden!

Alle zusammen:

Bild

8 MB PSRAM


8 MB PSRAM Upgrade Mod
Unterstützung für externen RAM
PSRAM / CE (Pin 1)> ESP32 GPIO 16
PSRAM SO (Pin 2)> Flash DO
PSRAM SIO [2] (Pin 3)> Flash WP
PSRAM SI (Pin 5)> Flash DI
PSRAM SCLK (Pin 6)> ESP32 GPIO 17
PSRAM SIO [3] (Pin 7)> Flash HOLD
PSRAM Vcc (Pin 8)> ESP32 VCC_SDIO


Leiterplattenantenne


Ich habe eine kleine 2,4-GHz-Leiterplattenantenne verwendet . Es befindet sich in der Eagle Autodesk-Bibliothek und nimmt einen kleinen Bereich ein. Sie können wahrscheinlich CERAMIC DIELECTRIC ANTENNA verwenden, aber Sie müssen es kaufen, und der Preis für eine PCB-Antenne ist etwas höher. Eine Keramikantenne ist jedoch weniger effektiv. Jede Option

Antennenauswahl Kurzanleitung Richtlinien für Antennendesign und HF-Layout eignen sich zur Überprüfung des Konzepts.

Bild



Ein bisschen über das Anpassen der Antenne




Die ESP32-Hardware-Designrichtlinien auf Seite 7 enthalten Richtlinien für die Implementierung eines HF-Filters:
Die Ausgangsimpedanz der HF-Pins von ESP32 (QFN 6 * 6) und ESP32 (QFN 5 * 5) beträgt (30 + j10) Ω bzw. (35 + j10) Ω
Verwenden Sie zum Berechnen das Online Smith Chart Tool . Die Hauptidee ist, bei (30 + j10) zum Mittelpunkt des Kreises zu gelangen. Hierbei handelt es sich jedoch um berechnete Daten, und die tatsächliche Verwendung der Parameter kann durch die Dicke der Spuren und der Leiterplatte sowie durch die Position relativ zu anderen Komponenten der Schaltung beeinflusst werden.



Dies ist nicht die einzige Antennenanpassungsschaltung. Zum Beispiel ist die Anpassung auf der esp32-pic

-Karte etwas anders: esp32-pico-kit-v4_schematic

Smith-Diagramm und Impedanzanpassung Die

Position der Antenne und der freie Bereich um sie herum sind ebenfalls wichtig. Wie ich bereits geschrieben habe, ist in meinem Fall die Position nicht optimal ausgewählt. Für die erste Iteration der Karte und die Überprüfung des Konzepts wird der



zweite Teil der Karte selbst und der dritten Portierung von Software gewidmet sein. Vielleicht passt alles in einen.

Ich werde auf dem Doom- Port von Espressif Systems ein bisschen weiterkommen. Der Port verwendet ILI9341, wir haben ST7789. Da jedoch die Initialisierung und Ausgabe des Puffers in einer separaten Datei ausgeführt und in separate Methoden unterteilt wird, sollte die Anpassung an meine Anzeige keine großen Schwierigkeiten verursachen.

  • Ili_init und displayTask sind für die Initialisierung der Anzeige verantwortlich
  • DisplayTask ist für die Anzeige verantwortlich.

displayTask
void IRAM_ATTR displayTask(void *arg) {
	int x, i;
	int idx=0;
	int inProgress=0;
	static uint16_t *dmamem[NO_SIM_TRANS];
	spi_transaction_t trans[NO_SIM_TRANS];
	spi_transaction_t *rtrans;

    esp_err_t ret;
    spi_bus_config_t buscfg={
        .miso_io_num=-1,
        .mosi_io_num=PIN_NUM_MOSI,
        .sclk_io_num=PIN_NUM_CLK,
        .quadwp_io_num=-1,
        .quadhd_io_num=-1,
        .max_transfer_sz=(MEM_PER_TRANS*2)+16
    };
    spi_device_interface_config_t devcfg={
        .clock_speed_hz=26000000,               //Clock out at 26 MHz. Yes, that's heavily overclocked.
        .mode=0,                                //SPI mode 0
        .spics_io_num=PIN_NUM_CS,               //CS pin
        .queue_size=NO_SIM_TRANS,               //We want to be able to queue this many transfers
        .pre_cb=ili_spi_pre_transfer_callback,  //Specify pre-transfer callback to handle D/C line
    };

	printf("*** Display task starting.\n");

    //Initialize the SPI bus
    ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
    assert(ret==ESP_OK);
    //Attach the LCD to the SPI bus
    ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
    assert(ret==ESP_OK);
    //Initialize the LCD
    ili_init(spi);

	//We're going to do a fair few transfers in parallel. Set them all up.
	for (x=0; x<NO_SIM_TRANS; x++) {
		dmamem[x]=pvPortMallocCaps(MEM_PER_TRANS*2, MALLOC_CAP_DMA);
		assert(dmamem[x]);
		memset(&trans[x], 0, sizeof(spi_transaction_t));
		trans[x].length=MEM_PER_TRANS*2;
		trans[x].user=(void*)1;
		trans[x].tx_buffer=&dmamem[x];
	}
	xSemaphoreGive(dispDoneSem);

	while(1) {
		xSemaphoreTake(dispSem, portMAX_DELAY);
//		printf("Display task: frame.\n");
#ifndef DOUBLE_BUFFER
		uint8_t *myData=(uint8_t*)currFbPtr;
#endif

		send_header_start(spi, 0, 0, 320, 240);
		send_header_cleanup(spi);
		for (x=0; x<320*240; x+=MEM_PER_TRANS) {
#ifdef DOUBLE_BUFFER
			for (i=0; i<MEM_PER_TRANS; i+=4) {
				uint32_t d=currFbPtr[(x+i)/4];
				dmamem[idx][i+0]=lcdpal[(d>>0)&0xff];
				dmamem[idx][i+1]=lcdpal[(d>>8)&0xff];
				dmamem[idx][i+2]=lcdpal[(d>>16)&0xff];
				dmamem[idx][i+3]=lcdpal[(d>>24)&0xff];
			}
#else
			for (i=0; i<MEM_PER_TRANS; i++) {
				dmamem[idx][i]=lcdpal[myData[i]];
			}
			myData+=MEM_PER_TRANS;
#endif
			trans[idx].length=MEM_PER_TRANS*16;
			trans[idx].user=(void*)1;
			trans[idx].tx_buffer=dmamem[idx];
			ret=spi_device_queue_trans(spi, &trans[idx], portMAX_DELAY);
			assert(ret==ESP_OK);

			idx++;
			if (idx>=NO_SIM_TRANS) idx=0;

			if (inProgress==NO_SIM_TRANS-1) {
				ret=spi_device_get_trans_result(spi, &rtrans, portMAX_DELAY);
				assert(ret==ESP_OK);
			} else {
				inProgress++;
			}
		}
#ifndef DOUBLE_BUFFER
		xSemaphoreGive(dispDoneSem);
#endif
		while(inProgress) {
			ret=spi_device_get_trans_result(spi, &rtrans, portMAX_DELAY);
			assert(ret==ESP_OK);
			inProgress--;
		}
	}
}


Video Esp32-Doom schnelle Demo



Die Board-Bestellung wurde an die Jlcpcb-Fabrik gesendet.

Herausforderung gestartet!

All Articles