Указатель мыши не хочет хорошо работать с ESP32 при использовании библиотеки FABGL, используя пример эмулятора ПКC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Указатель мыши не хочет хорошо работать с ESP32 при использовании библиотеки FABGL, используя пример эмулятора ПК

Сообщение Anonymous »

В настоящее время у меня есть серьезная проблема с ESP32, и я использую указатель мыши в отношении того, чтобы получить ESP32 для отображения курсора на моем VGA или видео -экране массива Graphics, я успешно внедрил аналогичные сопротивления, чтобы обеспечить правильную сигнализацию VGA, и до сих пор может получить как мышь, так и клавиатуру для работы с помощью базовой сигнализации, однако, кондиционер MASOR не показывают правильно. Я пытался пойти на аналогичные форумы и опубликовать аналогичные вопросы на этих форумах Arduino, однако, до сих пор я не получил должного ответа от любого такого пользователя на этом форуме. Вот ссылка на то, когда я опубликовал оригинальный вопрос еще в 2021 году: https://forum.arduino.cc/t/problem-with ... 987образно graphical functionality to work properly for the FabGL PC Emulator example, in addition to this post not bearing fruit, here is both the example code provided by Mr. Fabrizo himself, my current pinout using the alternative 680, 150, 2000, and 470 ohm resistors for the RGB Signals, and of course the normal pinout for the FabGl library:

Код: Выделить всё

- to run this application you need an ESP32 with PSRAM installed and an SD-CARD slot (ie TTGO VGA32 v1.4 or FabGL Development Board with WROVER)
- open this with Arduino and make sure PSRAM is DISABLED
- partition scheme must be: Huge App
- compile and upload the sketch

#pragma message "This sketch requires Tools->Partition Scheme = Huge APP"

#include 

#include "esp32-hal-psram.h"
extern "C" {
#include "esp_spiram.h"
}
#include "esp_sntp.h"

#include
#include 
#include 

#include "fabgl.h"

#include "mconf.h"
#include "machine.h"

// UART Pins for USB serial
#define UART_URX 3
#define UART_UTX 1

using std::unique_ptr;

using fabgl::StringList;
using fabgl::imin;
using fabgl::imax;

Preferences   preferences;
InputBox      ibox;
Machine     * machine;

// noinit! Used to maintain datetime between reboots
__NOINIT_ATTR static timeval savedTimeValue;

static bool wifiConnected = false;
static bool downloadOK    = false;

// try to connected using saved parameters
bool tryToConnect()
{
bool connected = WiFi.status() == WL_CONNECTED;
if (!connected) {
char SSID[32] = "";
char psw[32]  = "";
if (preferences.getString("SSID", SSID, sizeof(SSID)) && preferences.getString("WiFiPsw", psw, sizeof(psw))) {
ibox.progressBox("", "Abort", true, 200, [&](fabgl::ProgressForm * form) {
WiFi.begin(SSID, psw);
for (int i = 0; i < 32 && WiFi.status() != WL_CONNECTED; ++i) {
if (!form->update(i * 100 / 32, "Connecting to %s...", SSID))
break;
delay(500);
if (i == 16)
WiFi.reconnect();
}
connected = (WiFi.status() == WL_CONNECTED);
});
// show to user the connection state
if (!connected) {
WiFi.disconnect();
ibox.message("", "WiFi Connection failed!");
}
}
}
return connected;
}

bool checkWiFi()
{
wifiConnected = tryToConnect();
if (!wifiConnected) {

// configure WiFi?
if (ibox.message("WiFi Configuration", "Configure WiFi?", "No", "Yes") == InputResult::Enter) {

// repeat until connected or until user cancels
do {

// yes, scan for networks showing a progress dialog box
int networksCount = 0;
ibox.progressBox("", nullptr, false, 200, [&](fabgl::ProgressForm * form) {
form->update(0, "Scanning WiFi networks...");
networksCount = WiFi.scanNetworks();
});

// are there available WiFi?
if (networksCount > 0) {

// yes, show a selectable list
StringList list;
for (int i = 0; i < networksCount; ++i)
list.appendFmt("%s (%d dBm)", WiFi.SSID(i).c_str(), WiFi.RSSI(i));
int s = ibox.menu("WiFi Configuration", "Please select a WiFi network", &list);

// user selected something?
if (s >  -1) {
// yes, ask for WiFi password
char psw[32] = "";
if (ibox.textInput("WiFi Configuration", "Insert WiFi password", psw, 31, "Cancel", "OK", true) == InputResult::Enter) {
// user pressed OK, connect to WiFi...
preferences.putString("SSID", WiFi.SSID(s).c_str());
preferences.putString("WiFiPsw", psw);
wifiConnected = tryToConnect();
// show to user the connection state
if (wifiConnected)
ibox.message("", "Connection succeeded!");
} else
break;
} else
break;
} else {
// there is no WiFi
ibox.message("", "No WiFi network found!");
break;
}
WiFi.scanDelete();

} while (!wifiConnected);

}

}

return wifiConnected;
}

// handle soft restart
void shutdownHandler()
{
// save current datetime into Preferences
gettimeofday(&savedTimeValue, nullptr);
}

void updateDateTime()
{
// Set timezone
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
tzset();

// get datetime from savedTimeValue? (noinit section)
if (esp_reset_reason() == ESP_RST_SW) {
// adjust time taking account elapsed time since ESP32 started
savedTimeValue.tv_usec += (int) esp_timer_get_time();
savedTimeValue.tv_sec  += savedTimeValue.tv_usec / 1000000;
savedTimeValue.tv_usec %= 1000000;
settimeofday(&savedTimeValue, nullptr);
return;
}

if (checkWiFi()) {

// we need time right now
ibox.progressBox("", nullptr, true, 200, [&](fabgl::ProgressForm * form) {
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, (char*)"pool.ntp.org");
sntp_init();
for (int i = 0; i < 12 && sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED; ++i) {
form->update(i * 100 / 12, "Getting date-time from SNTP...");
delay(500);
}
sntp_stop();
ibox.setAutoOK(2);
ibox.message("", "Date and Time updated.  Restarting...");
#ifndef FABGL_EMULATED
esp_restart();
#endif
});

} else {

// set default time
auto tm = (struct tm){ .tm_sec  = 0, .tm_min  = 0, .tm_hour = 8, .tm_mday = 14, .tm_mon  = 7, .tm_year = 84 };
auto now = (timeval){ .tv_sec = mktime(&tm) };
settimeofday(&now, nullptr);

}
}

// download specified filename from URL
bool downloadURL(char const * URL, FILE * file)
{
downloadOK = false;

char const * filename = strrchr(URL, '/') + 1;

ibox.progressBox("", "Abort", true, 380, [&](fabgl::ProgressForm * form) {
form->update(0, "Preparing to download %s", filename);
HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.begin(URL);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
if (file) {
int tlen = http.getSize();
int len = tlen;
auto buf = (uint8_t*) SOC_EXTRAM_DATA_LOW; // use PSRAM as buffer
WiFiClient * stream = http.getStreamPtr();
int dsize = 0;
while (http.connected() && (len > 0 || len == -1)) {
size_t size = stream->available();
if (size) {
int c = stream->readBytes(buf, size);
auto wr = fwrite(buf, 1, c, file);
if (wr != c) {
dsize = 0;
break;  // writing failure!
}
dsize += c;
if (len > 0)
len -= c;
if (!form->update((int64_t)dsize * 100 / tlen, "Downloading %s (%.2f / %.2f MB)", filename, (double)dsize / 1048576.0, tlen / 1048576.0))
break;
}
}
downloadOK = (len == 0 || (len == -1 && dsize > 0));
}
}
http.end();
});

return downloadOK;
}

// return filename if successfully downloaded or already exist
char const * getDisk(char const * url)
{
FileBrowser fb(SD_MOUNT_PATH);

char const * filename = nullptr;
if (url) {
if (strncmp("http://", url, 7) == 0 || strncmp("https://", url, 7) == 0) {
// this is actually an URL
filename = strrchr(url, '/') + 1;
if (filename && !fb.exists(filename, false)) {
// disk doesn't exist, try to download
if (!checkWiFi())
return nullptr;
auto file = fb.openFile(filename, "wb");
bool success = downloadURL(url, file);
fclose(file);
if (!success) {
fb.remove(filename);
return nullptr;
}
}
} else {
// this is just a file
if (fb.filePathExists(url))
filename = url;
}
}
return filename;
}

// user pressed SYSREQ (ALT + PRINTSCREEN)
void sysReqCallback()
{
machine->graphicsAdapter()->enableVideo(false);
ibox.begin(VGA_640x480_60Hz, 500, 400, 4);

int s = ibox.menu("", "Select a command", "Restart Emulator;Restart Machine;Mount Disk;Continue");
switch (s) {

// Restart Emulator
case 0:
esp_restart();
break;

// Restart Machine
case 1:
machine->trigReset();
break;

// Mount Disk
case 2:
{
int s = ibox.menu("", "Select Drive", "Floppy A (fd0);Floppy B (fd1)");
if (s > -1) {
constexpr int MAXNAMELEN = 256;
unique_ptr dir(new char[MAXNAMELEN + 1] { '/', 'S', 'D', 0 } );
unique_ptr filename(new char[MAXNAMELEN + 1] { 0 } );
if (machine->diskFilename(s))
strcpy(filename.get(), machine->diskFilename(s));
if (ibox.fileSelector("Select Disk Image", "Image Filename", dir.get(), MAXNAMELEN, filename.get(), MAXNAMELEN) == InputResult::Enter) {
machine->setDriveImage(s, filename.get());
}
}
break;
}

// Continue
default:
break;
}

ibox.end();
PS2Controller::keyboard()->enableVirtualKeys(false, false); // don't use virtual keys
machine->graphicsAdapter()->enableVideo(true);
}

void setup()
{
Serial.begin(115200); delay(500);  printf("\n\n\nReset\n\n");// DEBUG ONLY

disableCore0WDT();
delay(100); // experienced crashes without this delay!
disableCore1WDT();

preferences.begin("PCEmulator", false);

// uncomment to clear preferences
//preferences.clear();

// save some space reducing UI queue
fabgl::BitmappedDisplayController::queueSize = 128;

ibox.begin(VGA_640x480_60Hz, 500, 400, 4);
ibox.setBackgroundColor(RGB888(0, 0, 0));

ibox.onPaint = [&](Canvas * canvas) { drawInfo(canvas); };

// we need PSRAM for this app, but we will handle it manually, so please DO NOT enable PSRAM on your development env
#ifdef BOARD_HAS_PSRAM
ibox.message("Warning!", "Please disable PSRAM to improve performance!");
#endif

// note: we use just 2MB of PSRAM so the infamous PSRAM bug should not happen. But to avoid gcc compiler hack (-mfix-esp32-psram-cache-issue)
// we enable PSRAM at runtime, otherwise the hack slows down CPU too much (PSRAM_HACK is no more required).
if (esp_spiram_init() != ESP_OK)
ibox.message("Error!", "This app requires a board with PSRAM!", nullptr, nullptr);

#ifndef BOARD_HAS_PSRAM
esp_spiram_init_cache();
#endif

if (!FileBrowser::mountSDCard(false, SD_MOUNT_PATH, 8))   // @TODO: reduce to 4?
ibox.message("Error!", "This app requires a SD-CARD!", nullptr, nullptr);

// uncomment to format SD!
//FileBrowser::format(fabgl::DriveType::SDCard, 0);

esp_register_shutdown_handler(shutdownHandler);

updateDateTime();

// machine configurations
MachineConf mconf;

// show a list of machine configurations

ibox.setAutoOK(6);
int idx = preferences.getInt("dconf", 0);

for (bool showDialog = true; showDialog; ) {

loadMachineConfiguration(&mconf);

StringList dconfs;
for (auto conf = mconf.getFirstItem(); conf; conf = conf->next)
dconfs.append(conf->desc);
dconfs.select(idx, true);

ibox.setupButton(0, "Files");
ibox.setupButton(1, "Machine", "Edit;New;Remove", 52);
auto r = ibox.select("Machine Configurations", "Please select a machine configuration", &dconfs, nullptr, "Run");

idx = dconfs.getFirstSelected();

switch (r) {
case InputResult::ButtonExt0:
// Browse Files
ibox.folderBrowser("Browse Files", SD_MOUNT_PATH);
break;
case InputResult::ButtonExt1:
// Machine
switch (ibox.selectedSubItem()) {
// Edit
case 0:
editConfigDialog(&ibox, &mconf, idx);
break;
// New
case 1:
newConfigDialog(&ibox, &mconf, idx);
break;
// Remove
case 2:
delConfigDialog(&ibox, &mconf, idx);
break;
};
break;
case InputResult::Enter:
// Run
showDialog = false;
break;
default:
break;
}

// next selection will not have timeout
ibox.setAutoOK(0);
}

idx = imax(idx, 0);
preferences.putInt("dconf", idx);

// setup selected configuration
auto conf = mconf.getItem(idx);

char const * diskFilename[DISKCOUNT];
downloadOK = true;
for (int i = 0; i < DISKCOUNT && downloadOK; ++i)
diskFilename[i] = getDisk(conf->disk[i]);

if (!downloadOK || (!diskFilename[0] && !diskFilename[2])) {
// unable to get boot disks
ibox.message("Error!", "Unable to get system disks!");
esp_restart();
}

if (wifiConnected) {
// disk downloaded from the Internet, need to reboot to fully disable wifi
ibox.setAutoOK(2);
ibox.message("", "Disks downloaded.  Restarting...");
#ifndef FABGL_EMULATED
esp_restart();
#endif
}

ibox.end();

// without WiFi it is possible to increase SD card speed
FileBrowser::setSDCardMaxFreqKHz(SDMMC_FREQ_DEFAULT);
FileBrowser::remountSDCard();

machine = new Machine;

machine->setBaseDirectory(SD_MOUNT_PATH);
for (int i = 0; i < DISKCOUNT; ++i)
machine->setDriveImage(i, diskFilename[i], conf->cylinders[i], conf->heads[i], conf->sectors[i]);

machine->setBootDrive(conf->bootDrive);

auto serial1 = new SerialPort;
serial1->setSignals(UART_URX, UART_UTX);
machine->setCOM1(serial1);

/*
printf("MALLOC_CAP_32BIT : %d bytes (largest %d bytes)\r\n", heap_caps_get_free_size(MALLOC_CAP_32BIT), heap_caps_get_largest_free_block(MALLOC_CAP_32BIT));
printf("MALLOC_CAP_8BIT  : %d bytes (largest %d bytes)\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT), heap_caps_get_largest_free_block(MALLOC_CAP_8BIT));
printf("MALLOC_CAP_DMA   : %d bytes (largest %d bytes)\r\n\n", heap_caps_get_free_size(MALLOC_CAP_DMA), heap_caps_get_largest_free_block(MALLOC_CAP_DMA));

heap_caps_dump_all();

machine->setSysReqCallback(sysReqCallback);

machine->run();
}

#if FABGLIB_VGAXCONTROLLER_PERFORMANCE_CHECK
namespace fabgl {
extern volatile uint64_t s_vgapalctrlcycles;
}
using fabgl::s_vgapalctrlcycles;
#endif

void loop()
{

#if FABGLIB_VGAXCONTROLLER_PERFORMANCE_CHECK
static uint32_t tcpu = 0, s1 = 0, count = 0;
tcpu = machine->ticksCounter();
s_vgapalctrlcycles = 0;
s1 = fabgl::getCycleCount();
delay(1000);
printf("%d\tCPU: %d", count, machine->ticksCounter() - tcpu);
printf("   Graph: %lld / %d   (%d%%)\n", s_vgapalctrlcycles, fabgl::getCycleCount() - s1, (int)((double)s_vgapalctrlcycles/240000000*100));
++count;
#else

vTaskDelete(NULL);

#endif
}
В дополнение к коду, включенному выше, я также попытался увидеть, есть ли какие -либо другие общие черты в том, как работают мышь и клавиатуру в рамках исходного исходного кода, как видно в этой ссылке: https://github.com/fdivitto/fabgl/tree/ ... pcemulator, но я не смотрю, что есть, что -то, что есть, что -то, что есть, я не смотрел, что не так уж и подумал. Проблема могла бы быть, и, кроме того, не упоминаются об этой проблеме на вкладке «Проблемы библиотеки», поэтому я также не могу реализовать правильные исправления для этого. Эти ссылки, как и сейчас. Вот как предполагается, что резисторы должны быть реализованы в Fabgl Libaray:


Вот как должен выглядеть обычный экран fabgl с указателем мыши, тогда как это выглядит мой экран после того, как я загружаю свой компьютер на первый раз:

это проблема с резисторами? Если да, то почему IR -датчики мыши действуют как задумано и зажигают, когда я направо и щелкнул слева? Если эта проблема здесь не может быть решена, возможно ли будет другое место или четырехм, в котором я могу решить эту проблему? Большое спасибо, и любая помощь будет одобрена.

Подробнее здесь: https://stackoverflow.com/questions/795 ... gl-library
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»