Register

Transfer Files from Arduino to Casio-FX-CG20

Discuss issues related to Calculator Hacking/Modding.
Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Wed Apr 11, 2018 1:01 pm

Hello, i'm currently working on sending Files(mainly Images) from an Arduino pro mini over the 3-Pin connector/serial port to my Casio FX-CG20. Im already experienced in c++ programming, but the pure byte sending is kinda new for me.
I'm not sure if im calculating the checksum the right way, or if im forgetting something(sending some bytes inbetween, etc) for the constant connection between my arduino and my casio.
And i also have no idea why to send the //??? bytes, i just copied them from the example. I tested this program on my arduino connected to the calculator, but it did not work.
This project is kinda important for me and should be done soon, so i hope someone here can help me. Im also willing to pay money for a full solution, if someone is interested.
Anyways thanks for reading and i hope you were able to understand my sometimes bad english (:

I looked at http://www.casiopeia.net/forum/downloads.php?view=detail&df_id=72 for the calculator and at https://www.arduino.cc/reference/en/ for the arduino and came up with:
Code: Select all
#include <AltSoftSerial.h>
AltSoftSerial  casio(8,9);//RX, TX

String getHex(int w, int hex_len)//should convert int into ascii-hex string
{
  String temp(w,HEX);
if(temp.length()>hex_len)
{
  return temp.substring(temp.length()-hex_len,temp.length());
}
else if(temp.length()<hex_len)
{
  String ns="";
  ns.reserve(hex_len);
  for(int i=0;i<hex_len;i++)
  {
    ns+="0";
  }
  int diffrence = hex_len-temp.length();
  for(int i=diffrence;i<hex_len;++i)
  {
    ns.setCharAt(i,temp[i-diffrence]);
  }
  return ns;
}
else
{
  return temp;
}
 
}

void check(String start)//should send the check | 00=first, 01 after
{
  Serial.write("out:0x05 00 0 70\n");
  casio.write(0x05);
  casio.write(start.c_str());//subtype
  casio.write("0");
  if ( start.equals("00") )
  {
    casio.write("70");//converted from hex 0x3730
  }
  else
  {
    casio.write("6F");
  }
}

void ack()
{
  Serial.write("out:0x06 00 0 70\n");
  delay(10);
  casio.write(0x06);
  casio.write("00");//subtype
  casio.write("0");
  casio.write("70");
}

bool getCheck(String start, String input)//should get the check | 00=first, 01 after
{
  Serial.write("check\n");

  if(input.equals("00070"))//forum cant read the first ascii char, its the symbol in ascii relalitve to 0x05
  {
     return true;
  }
  return false;
}

int getAck()
{
  delay(10);
  String input="";
  while(casio.available())
  {
  byte b = casio.read();
  input+=(char)b;//not sure, if its in hex
  }

  Serial.write("in:");
  Serial.write(input.c_str());
  Serial.write("\n");
 
  if(input.equals("00070"))//forum cant read the first ascii char, its the symbol in ascii relalitve to 0x06
  {
    return 1;
  }
  if(getCheck("00",input)==true||getCheck("01",input)==true)
  {
    return 2;
  }
  return 0;
}

void sendDataIN(String data, int count, int number)//same as below
{
  Serial.write("Data Packet");
  Serial.write(count);
  Serial.write("\n");
  String countS = getHex(count, 4);
  String numberS = getHex(number, 4);
  int sizeR = 8 + data.length();
  String sizeS = getHex(sizeR, 4);

  casio.write(0x02);//data
  casio.write("45");//file data
  casio.write("1");//extended
  casio.write(sizeS.c_str());//byte size of following

  casio.write(countS.c_str());//total number of data packets
  casio.write(numberS.c_str());//number of current package
  casio.write(data.c_str());//file data

  char sum = '4' + '5' + '1';
  int i = 0;
  for ( ; i < 4; ++i )
  {
    sum += sizeS.charAt(i);
    sum += countS.charAt(i);
    sum += numberS.charAt(i);
  }
  i = 0;
  for ( ; i < data.length(); ++i )
  {
    sum += data.charAt(i);
  }
  sum = (~sum ) + (char)1;
  String sumS = getHex(sum, 2);
 
  casio.write(sumS.c_str());//checksum
 
  Serial.write("Data out:0x02 45 1 ");
  Serial.write(sizeS.c_str());Serial.write(" ");
  Serial.write(countS.c_str());Serial.write(" ");
  Serial.write(numberS.c_str());Serial.write(" ");
  Serial.write(data.c_str());Serial.write(" ");
  Serial.write(sumS.c_str());Serial.write("\n");
 
  if(getAck()!=1)
  {
    Serial.write("Error sendDataIN \n");//debug log
    sendDataIN(data, count, number);
  }
}

void sendData(String data)//hopefully working, not sure with the own checksum calculation tho
{
  Serial.write("sending Data \n");
  int count = ceil((double) data.length() / (double) 256);
  int number = 1;
  while ( number <= count )
  {
    if ( data.length() > 256 )
    {
      sendDataIN(data.substring(0, 256), count, number);
      data = data.substring(256, data.length());
    }
    else
    {
      sendDataIN(data, count, number);
    }
    number++;
  }
}

void sendFile(String fName, int fSize, String inputdata)//inputdata as temp placeholder
{
  String fileSize = getHex(fSize,8);//filesize in ascii hex
  String fns = getHex(fName.length(),2);//filenamesize
  String sds = getHex((28 + fName.length()),4); //size of all data fields

  String over = "00";//later change it to 01

  casio.write(0x01);//command | everything except this in ascii hex
  //maybe change evey write call with "text" to print? ascii encoding ???https://www.arduino.cc/en/Serial/Write | https://www.arduino.cc/en/Serial/Print
  casio.write("45");//file transfer | 2b
  casio.write("1");//extended | 1b
  casio.write(sds.c_str());//byte size of following(without checksum) | 4b  | calculated from all data fields

  casio.write(over.c_str());//override | 00=confirm, 01=terminate, 02=force
  casio.write("00");//data type
  casio.write(fileSize.c_str());//filesize | 8b
  casio.write("00");//sd1 |2b
  casio.write(fns.c_str());//sd2: size of filename | 2b
  casio.write("00");//sd3
  casio.write("00");//sd4
  casio.write("04");//sd5: size of drive name
  casio.write("00");//sd6
  casio.write(fName.c_str());//d2: filename
  casio.write("fls0");//d5: drive name

  char sum ='4'+'5'+'1'+'0'+'0'+'0'+'0'+'0'+'0'+'0'+'0'+'0'+'0'+'4'+'0'+'0'+'f'+'l'+'s'+'0';//change when override changes
  over;sum+='0';//override bit, change to 1 later
  int i = 0;
  for ( ; i < 2; ++i )
  {
    sum += fns.charAt(i);
  }
  i = 0;
  for ( ; i < 4; ++i )
  {
    sum += sds.charAt(i);
  }
  i=0;
  for ( ; i < 8; ++i )
  {
    sum += fileSize.charAt(i);
  }
  i=0;
  for ( ; i < fName.length(); ++i )
  {
    sum += fName.charAt(i);
  }
  sum = (~sum ) + (char)1;//working

  String sumS = getHex(sum, 2);
 
  casio.write(sumS.c_str());//checksum 2 byte

  Serial.write("sending File, out:0x01 45 1 ");
  Serial.write(sds.c_str());Serial.write(" ");Serial.write(over.c_str());Serial.write(" 00 ");
  Serial.write(fileSize.c_str());Serial.write(" 00 ");
  Serial.write(fns.c_str());Serial.write(" 00 00 04 00 ");
  Serial.write(fName.c_str());Serial.write(" fls0 ");
  Serial.write(sumS.c_str());Serial.write("\n");

  delay(100);
 
  if(getAck()!=1)
  {
    Serial.write("Error sendFile \n");//debug log
  }
  else
  {
    sendData(inputdata);//size of data is 8 bytes
  }
}

void setup()//setup will be called once when arduino powers up
{
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  while ( !Serial ){;}
  casio.begin(9600);
}
bool started = false;
// the loop function runs over and over again forever
void loop()
{
  delay(2500);//wait 2.5 sec
  if(started==false)
  {
    check("00");
    int a = getAck();
    while(a>0)
    {
      if(a==2)
      {
        ack();//acknowledge the check from the other side->would make this to secondary?
      }
      else if(a==1)
      {
        started=true;//casio accepted check
      }
      a=getAck();
    }
  }
  else
  {
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    sendFile("FILENAME",8,"data1234");

  }

    Serial.write("Remaining:\n");
    bool empty = true;
    while(casio.available())
    {
      Serial.write((char)casio.read());//not sure, if its in hex
      empty = false;
     }
     if(empty==false){
       Serial.write("\n");
     }
  delay(2500);//wait 2.5 sec
  digitalWrite(LED_BUILTIN, LOW);
}
Last edited by randomrguy on Mon Apr 16, 2018 10:26 pm, edited 3 times in total.

Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Wed Apr 11, 2018 1:12 pm

.
Last edited by randomrguy on Thu Apr 12, 2018 12:27 pm, edited 1 time in total.

Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Wed Apr 11, 2018 1:50 pm

I updated the Code now with checking for Ack, but its still not working. As soon as i connect the calculator to the Arduino, change cable to 3pin and press "RECV" my console is printing: _|0000000|_Error check
_|0000000|_Error check
_|00000000|_Error check
_|00|_Error check
_|000000|_Error check
_|000000|_Error check
_|000000|_Error check
_|000000|_Error check
_|000000|_Error check
_|0000000|_Error check
_|000000|_Error check
_|0000000|_Error check
_|000000|_Error check
_|0000000|_Error check
as response, where the __||__ are just seperators. I dont know why this is not working, could it maybe also be, because i updated the operating system of the casio?
I also have a problem with the forum, sometimes when i update my post, it just disappeares and i have to create it again. So i had to create the last post again, but i think it was because of my firefox addons/settings and it should be working now.
Also some comments in my code were missing and i updated them now.
I dont know what the bytes of the example(commented with //???) are send for.

Senior Member
User avatar
Posts: 593
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750 G II, Casio fx-9750 G II (SH4), Casio fx-9860G, Casio fx-9860 G SD, Casio fx-9860G Slim, Casio fx-9860 GII SD, Casio fx-9860 GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG 20, Casio Classpad fx-cp400, Casio fx-CG 50

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby SimonLothar » Sat Apr 14, 2018 8:35 am

randomrguy wrote:I updated the Code now with checking for Ack, but its still not working. As soon as i connect the calculator to the Arduino, change cable to 3pin and press "RECV" my console is printing: _|0000000|_Error check
_|0000000|_Error check
_|00000000|_Error check
_|00|_Error check
_|000000|_Error check
_|000000|_Error check
_|000000|_Error check
_|000000|_Error check
_|000000|_Error check
_|0000000|_Error check
_|000000|_Error check
_|0000000|_Error check
_|000000|_Error check
_|0000000|_Error check
as response, where the __||__ are just seperators. I dont know why this is not working, could it maybe also be, because i updated the operating system of the casio?
If "Error check" is 0xFF and the Zeros are binary zeros , this looks like a typical pattern of a baudrate-mismatch.

randomrguy wrote:I dont know what the bytes of the example(commented with //???) are send for.
These control codes are documented in fxReverse2x.pdf, which should be a part of fx_calculators_SuperH_based.chm ("Further reading").
I'll be back!

Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Sat Apr 14, 2018 7:30 pm

Error check is just my String to be printed when no ack package is received.

And the baudrates should be fine, if the casio baudrate is 9600 at default, because in the arduino i set it to 9600.

I've read the fxRReverse2x.pdf, but couldnt find anything about the commented bytes from your file transfer example.

Do you maybe have to set the baudrrate via
4.3.2 System command reference-"02":Set link settings
first and if so, how do you do that?


I would be very glad, if you could talk with me on discord/teamspeak/etc and maybe take a look via teamviewer. Just write me your prefered time(idk about the time zone, i'm in germany with UTC +2), if you have some free time available.

Senior Member
User avatar
Posts: 593
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750 G II, Casio fx-9750 G II (SH4), Casio fx-9860G, Casio fx-9860 G SD, Casio fx-9860G Slim, Casio fx-9860 GII SD, Casio fx-9860 GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG 20, Casio Classpad fx-cp400, Casio fx-CG 50

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby SimonLothar » Sun Apr 15, 2018 7:33 am

randomrguy wrote:Error check is just my String to be printed when no ack package is received.
Before starting a file transfer or any other commend, there should be ensured, that the check-packet is properly answered by the ack-packet (See fxReverse 4.10.1).
Could you log the bytes, which are actually exchanged by the serial interface and post them as hex-numbers?
F. i. like
out: 05 30 30 30 37 30
in: 06 30 30 30 37 30

randomrguy wrote:I've read the fxRReverse2x.pdf, but couldnt find anything about the commented bytes from your file transfer example.
See 4.3.1 of fxReverse
casio.write("00");//??? : SD1
casio.write("08");//??? : SD2 (in this case the length of D2 (FILENAME))
casio.write("00");//??? : SD3
casio.write("00");//??? : SD4

casio.write("04");//??? : SD5 (in this case the length of D5 (fls0))
casio.write("00");//??? : SD6
casio.write("FILENAME");//filename (D2)
casio.write("fls0");//??? D5 (the name of the drive to use (on the prizm, there is "fls0" only, which is the storage memory. On calculators with SD-card, there could be used "crd0" as well.))
I'll be back!

Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Sun Apr 15, 2018 3:57 pm

Thank you, i understand the bytes now and i also found out that the libary i used with the arduino wasnt working that well, so i'm using a diffrent one now and i managed to get the start working. Im gonna try the file transfer later today and post the results.
Last edited by randomrguy on Mon Apr 16, 2018 10:33 pm, edited 3 times in total.

Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Sun Apr 15, 2018 4:28 pm

I've updated my program now and with the new program im still having trouble sending files. I updated the main post with the new Code(finally got the checksum working), but im not sure, if i missed something. Can you take a look at it pls, because i'm not sure why it's still not working.
Everything in my Code looks fine and i'm sending the exact same bytes of your file transfer example, but im getting these errors:

It seems like the casio is just sending the same bytes back.
The only good thing is, that i got a FILENAME file on the casio with no data in it, when i press RECV at the beginning of the connection.

When i do not press RECV on the casio and just let the arduino transfer the file, im getting:

out:0x05 00 0 70
in: 0x05 00070 //maybe only delay from casios own check, or is it just sending the bytes back the same as below with the file transfer?
check
out:0x06 00 0 70
in:0x06 00070 //maybe only delay from casios own ack, or is it just sending the bytes back the same as below with the file transfer?
in:
check
check
Remaining:
sending File, out:0x01 45 1 0024 00 00 00000008 00 08 00 00 04 00 FILENAME fls0 56
in:0x01 4510024000000000008000800000400FILENAMEfls056
check
check
Error sendFile
Remaining:

When i manually press RECV on the casio after the connection check, im getting no bytes at all send back to the arduino(not even error package, or ack package) from the casio as a response to the file package.
The start with check/ack is the same as above.

Junior Member
Posts: 8
Joined: Tue Apr 10, 2018 10:55 pm
Calculators: Casio fx-CG 20

Re: Transfer Files from Arduino to Casio-FX-CG20

Postby randomrguy » Thu Apr 19, 2018 5:22 pm

Im not sure why the casio isnt responding in the right way. It's still just sending the same bytes back to me. Even when i got no message back, it was because of some random bytes before.

The log with the raw bytes send(as decimals) below the input:
out:0x05 00 0 70
in:0x05 00070//forum cant show the ascii char relative to 0x05
5 48 48 48 55 48
check
out:0x06 00 0 70
in:0x06 00070
6 48 48 48 55 48
in:

check
check
Remaining:
sending File, out:0x01 45 1 0024 00 00 00000008 00 08 00 00 04 00 FILENAME fls0 56
in:0x01 4510024000000000008000800000400FILENAMEfls056
1 52 53 49 48 48 50 52 48 48 48 48 48 48 48 48 48 48 48 56 48 48 48 56 48 48 48 48 48 52 48 48 70 73 76 69 78 65 77 69 102 108 115 48 53 54
check
check


The good thing is, i can already send files with data to the casio and its working kinda ok, but i can never be sure if the files arrived correctly, because the casio just isnt answering.

Return to Calculator Hacking/Modding Discussions

Who is online

Users browsing this forum: No registered users and 1 guest