Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » Données corrompues entre Casio et ESP32 (série)
Smartye Hors ligne Membre Points: 8 Défis: 0 Message

Données corrompues entre Casio et ESP32 (série)

Posté le 31/07/2025 04:35

Bonjour à tous,
Je travaille sur un projet où j’essaie d’établir une communication série entre ma Casio Graph 35+E II (fx-9750giii) et un ESP32, en passant par la prise jack TRS 2,5 mm. Je rencontre actuellement des problèmes de transmission : les données sont souvent corrompues ou incohérentes, et j’aimerais beaucoup avoir votre aide pour diagnostiquer le problème.

Configuration :
J’ai soudé des fils directement depuis la prise TRS vers l’ESP32.
La continuité des fils a été vérifiée et confirmée.
J’utilise le SDK fx-9860G de Casio.
Le port série est configuré en 9600 bauds, 8 bits de données, aucune parité, 1 bit d’arrêt (8N1).

Le problème :
Lorsque j’envoie le message "Hello World\r\n" depuis la calculatrice, il arrive qu’il soit reçu correctement sur l’ESP32, mais la plupart du temps, les données sont brouillées ou corrompues. Voici un exemple de ce que j’obtiens dans le moniteur série :

He▒▒▒▒World
He▒▒
    ▒▒ɱ▒5
         He▒▒▒▒World
He▒▒
    ▒▒ɱ▒5
         He▒▒
             ▒▒ɱ▒5
                  He▒▒
                      ▒▒ɱ▒5
                           He▒▒
                               ▒▒ɱ▒5
                                    He▒▒▒▒World

Parfois, le message passe correctement, ce qui me laisse penser que la connexion physique est probablement correcte, mais quelque chose perturbe toujours la transmission.

Mes questions :
Le problème pourrait-il venir du câblage ?
Est-ce que ma calculatrice pourrait avoir un défaut matériel ?
Y a-t-il une erreur dans le code ou dans l’initialisation du port série ?
Est-ce une incompatibilité au niveau du protocole (par exemple : niveaux de tension, stop bits, etc.) ?
Et parfois, le port série refuse tout simplement de s’ouvrir, sans raison évidente.

J’utilise les appels système (syscalls) listés sur cette page :
https://bible.planet-casio.com/simlo/chm/v20/fx_legacy_Serial.htm

Merci pour toute aide !

Calculator Code

/*
* =================================================================================
* Interactive Serial "Hello World" for Casio fx-9860G
* =================================================================================
*
* Description:
* This Add-In sends "Hello World" over the serial port (2.5mm TRS jack).
*
* Instructions:
* - Run the Add-In from the main menu.
* - Press [F1] to send the "Hello World" message.
* - Press [EXE] to close the serial port and exit the application.
*/

#include "fxlib.h"
#include <string.h>

/*
* =================================================================================
* Serial Syscall Definitions
* =================================================================================
* The standard fx-9860G SDK does not provide C headers for the serial port.
* We define them here using a C-based stub that calls the OS routines directly.
*/

/**
* @brief Syscall 0x0418: Opens the serial port with the given configuration.
*/
const unsigned int sc_serial_open[] = { 0xD201D002, 0x422B0009, 0x80010070, 0x0418 };
typedef int (*sc_serial_open_t)(unsigned char*);
#define Serial_Open ((sc_serial_open_t)sc_serial_open)

/**
* @brief Syscall 0x040E: Puts one byte into the serial transmit buffer.
* This is inspired by the Serial_BufferedTransmitOneByte example in the forum post.
*/
const unsigned int sc_serial_write_byte[] = { 0xD201D002, 0x422B0009, 0x80010070, 0x040E };
typedef int (*sc_serial_write_byte_t)(unsigned char);
#define Serial_WriteByte ((sc_serial_write_byte_t)sc_serial_write_byte)

/**
* @brief Syscall 0x0419: Closes the serial port.
*/
const unsigned int sc_serial_close[] = { 0xD201D002, 0x422B0009, 0x80010070, 0x0419 };
typedef int (*sc_serial_close_t)(int);
#define Serial_Close ((sc_serial_close_t)sc_serial_close)


/*
* =================================================================================
* Main Application
* =================================================================================
*/

// Global flag to track the serial port status
int g_is_port_open = 0;

/**
* @brief Sends the "Hello World" string character by character.
*/
void SendHelloWorld(void) {
    const char* message = "Hello World\n";
    int i;

    if (!g_is_port_open) {
        locate(1, 4);
        Print((unsigned char*)"Error: Port is not open!  ");
        Bdisp_PutDisp_DD();
        return;
    }

    for (i = 0; i < strlen(message); ++i) {
        Serial_WriteByte(message[i]);
    }
    
    locate(1, 4);
    Print((unsigned char*)"Sent: 'Hello World'      "); // Pad with spaces to clear previous messages
    Bdisp_PutDisp_DD();
}

int AddIn_main(int isAppli, unsigned short OptionNum)
{
    unsigned int key;
    unsigned char serial_config[] = {0, 5, 0, 0, 0, 0}; // 9600 baud, 8N1

    Bdisp_AllClr_DDVRAM();
    locate(1, 1);
    Print((unsigned char*)"Serial Communication Demo");
    locate(1, 2);
    Print((unsigned char*)"-----------------------");
    locate(1, 6);
    Print((unsigned char*)"[F1] Send 'Hello World'");
    locate(1, 7);
    Print((unsigned char*)"[EXE] Exit");
    
    // Attempt to open the serial port
    if (Serial_Open(serial_config) == 0) {
        g_is_port_open = 1;
        locate(1, 4);
        Print((unsigned char*)"Serial port opened.");
    } else {
        g_is_port_open = 0;
        locate(1, 4);
        Print((unsigned char*)"Error: Failed to open port");
    }
    Bdisp_PutDisp_DD();

    // Main event loop
    while(1)
    {
        GetKey(&key);
        if (key == KEY_CTRL_F1) {
            SendHelloWorld();
        }
        else if(key == KEY_CTRL_EXE) {
            break;
        }
    }

    // Close the port before exiting
    if (g_is_port_open) {
        Serial_Close(1);
    }

    return 1;
}

#pragma section _BR_Size
unsigned long BR_Size;
#pragma section

#pragma section _TOP
int InitializeSystem(int isAppli, unsigned short OptionNum)
{
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}
#pragma section


ESP32 Code
/*
* =================================================================================
* ESP32 Receiver for Casio fx-9860G Serial Communication
* =================================================================================
* Description:
* This code listens for serial data from a Casio calculator on HardwareSerial port 2.
* It's configured for 9600 baud, 8N1, to match the calculator's settings.
*/

// Define the pins for the secondary serial port (Serial2)
#define CALC_RX_PIN 16 // GPIO 16
#define CALC_TX_PIN 17 // GPIO 17

void setup() {
  Serial.begin(115200);
  
  // Initialize the secondary serial port to communicate with the calculator
  // Baud Rate: 9600
  // Config: SERIAL_8N1 (8 data bits, No parity, 1 stop bit)
  // Pins: RX on GPIO 16, TX on GPIO 17
  Serial2.begin(9600, SERIAL_8N1, CALC_RX_PIN, CALC_TX_PIN);

  Serial.println("\nESP32 Serial Receiver Initialized");
  Serial.println("---------------------------------");
  Serial.print("Listening on GPIO ");
  Serial.print(CALC_RX_PIN);
  Serial.println(" at 9600 baud...");
  Serial.println("Waiting for message from Casio calculator...");
}

void loop() {
  // Check if there is data available from the calculator
  if (Serial2.available()) {
    // Read the incoming byte from the calculator and write it to the Serial Monitor
    char receivedChar = Serial2.read();
    Serial.print(receivedChar);
  }
}



Cakeisalie5 Hors ligne Ancien administrateur Points: 1985 Défis: 11 Message

Citer : Posté le 31/07/2025 09:10 | #


Hey ! Pour son protocole natif, le système utilise 2 bits d'arrêt, et non 1 ; tu peux peut-être essayer ça ?

Plus d'infos : https://next.cahuteproject.org/topics/communication-protocols/seven.html
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blog
Cakeisalie5 Hors ligne Ancien administrateur Points: 1985 Défis: 11 Message

Citer : Posté le 31/07/2025 09:36 | #


Si le nombre de bits d'arrêt s'avère ne pas être la solution, j'invoque @Dark Storm qui de mémoire a déjà joué avec une machine comme ça (Arduinl ?) pour check le code côté ESP32
Respirateur d'air, BDFL de Cahute, des utilitaires de communication pour calculatrices CASIO.


Mon blog
Dark storm Hors ligne Labélisateur Points: 11648 Défis: 179 Message

Citer : Posté le 31/07/2025 09:50 | #


Invocation acceptée.

Normalement les paramètres par défaut de l’objet Serial de la lib Arduino sont suffisants, ie begin(115200).
Je connais pas la syntaxe Serial2.begin(baudrate, params, pin_rx, pin_tx), ayant l’habitude de construire un SoftwareSerial(pin_rx, pin_tx) puis l’utiliser. Mais ça devrait pas changer grand chose.

Coté calculatrice par contre, je vois que tu as serial_config[] = {0, 5, 0, 0, 0, 0};. J’ai toujours utilisé serial_config[] = {0, 8, 0, 0, 0, 0}; (à priori 115200 bauds vs 9600) mais là encore ça devrait pas poser problème.

Y'a Ziqumu qui avait fait un tuto, disponible ici, avec la vidéo correspondante .

Pour ma part j’avais fait y'a bien longtemps un utilitaire pour transférer des fichiers : Serial_DLFile. Ça marchait bien donc pas de raisons que tu n'y arrive pas

La fonction que j’utilisais pour récupérer un fichier :
int get_file(unsigned char* buffer, int size)
{
    unsigned char config[] = {0, 9, 0, 0, 0, 0};
    short data;
    int error;
    int data_size;
    int i = 0;

    print_loading_box((unsigned char*)"LOADING...");

    while(Serial_IsOpen() != 1) Serial_Open(config);

    Serial_ClearReceiveBuffer();

    while(i < size)
    {
        print_loading_bar(i, size);

        data_size = Serial_GetRxBufferSize();
        
        if(data_size > 0)
        {
            error = Serial_ReadBytes(buffer + i, data_size, &data);
        
            if(error == 0)
            {
                i += data;
            }
        }

        Sleep(20);

        if(IsKeyDown(KEY_CTRL_AC))
        {
            print_msg((unsigned char*)"ERROR!", (unsigned char*)"Process aborted");
            return 1;
        }
    }

    while(Serial_IsOpen() != 3) Serial_Close(0);

    return 0;
}

Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Smartye Hors ligne Membre Points: 8 Défis: 0 Message

Citer : Posté le 31/07/2025 18:18 | #


Bonjour à tous,
J’ai remarqué un comportement étrange avec le port série de ma calculatrice. Il ne fonctionne que si j’appuie sur le bouton de réinitialisation à l’arrière de la calculatrice, puis que je lance l’add-in. Si je quitte l’add-in et que je le relance, le port série ne s’ouvre plus correctement.

Est-ce que quelqu’un a déjà rencontré ce problème ? Y a-t-il un moyen de réinitialiser ou de réactiver le port série sans devoir redémarrer la calculatrice à chaque fois ?

Je débute en programmation C, donc toute aide ou explication serait la bienvenue. Merci d’avance !
Loieducode Hors ligne Membre Points: 203 Défis: 6 Message

Citer : Posté le 31/07/2025 18:49 | #


Je ne connais pas trop le comportement des syscalls serial sur les caltos monochrome mais Serial_WriteByte(syscall 0x40E) a l'air d'écrire dans un buffer au lieu d'envoyer directement
Apparement, le syscall 0x410 envoie directement, mais il doit y avoir une meilleure solution
Looking for a steel cable

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2025 | Il y a 108 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd