This blog post describes a project called the Mini Experimenter, that might be useful for schools and kids. It allows for sensor measurements to be taken using a Casio calculator. The measurements can be recorded locally, charted, and processed in any way that a typical graphing calculator supports. The result can then be automatically be sent to an IoT hub location. I liked the idea of using a calculator for this project, because it’s something eventually all schoolkids own, and so there is some familiarity there.
The project was rapidly prototyped over a couple of days during Xmas after bouncing some ideas off a colleague. It is still a work-in-progress, but the core functionality works.
The 50-second video below shows a demonstration of some of the functionality. This demo shows the calculator’s in-built logger software in use with the project, but it is also possible to write your own program to run on the calculator since it is programmable.
What else is out there?
There are some existing data logger products intended for connecting to calculators, but they do not support cloud connections. Also, they have a higher cost (around £150 for some products like CLAB). This solution is open source and perhaps a tenth of the cost. Casio offers a more expensive higher-end EA-200 data logger product that can connect to calculators, but it is hard to find, it doesn’t seem to be sold in the UK at least.
The Mini Experimenter does not meet the same level of performance (yet), because I was not able to figure out all of the secrets of the Casio communications protocol. I think it’s a small step to more completely understand it, and it would be easy to do so if anyone owns a CLAB or EA-200 product, by snooping on the communications. I do not own these products.
This project was tested on a fx-CG50 calculator, but it might work with some of the other recent Casio graphing calculators too. This specific project as it stands is unlikely to work with older calculators, which used a different protocol that is already documented elsewhere.
How does it all fit together?
A picture says a thousand words, so the diagram below can be used to see approximately how the solution works.
The Casio calculator connects to the microcontroller using a . Refer to the table in the diagram below to see where the wires need to be soldered. Note that the connector needs a thin outer plastic body (7.5 mm or less) otherwise it won’t fit the recess when plugging it into the calculator. It’s possible to shave off some plastic to achieve that, or just discard the plastic barrel and use heatshrink.
A couple of different microcontroller boards have been tested. The easiest one to use is the Silicon Labs , because there are only three wires to solder. Anyone parent or teacher could do that, with no prior soldering experience. The Thunderboard Sense 2 has inbuilt sensors, so no additional soldering is needed.
The Thunderboard Sense 2 has in-built wireless BLE, however I did not explore that. It could be used to upload data to a mobile phone, since most children nowadays may own those at some point too.
Another option is to use an ESP32 based board. I tested with an ESP32-WROOM-32 module. Again there are just the three connections to solder for the communication to the calculator to work, however the ESP32 boards do not usually contain any on-board sensors. An external sensor would need to be wired up. For now I connected a to the ESP32. The DRV425 is a fluxgate magnetometer, a super-sensitive magnetic field measurement device. The output from the sensor is an analog voltage between 0V and 3.3V, and it connected directly to the analog input pin on the ESP32 module. The code could be extended to allow for I2C sensors to be connected too.
Thunderboard Sense 2
The contains a lot of in-built sensors! For now I only tried the light sensor.
The board can be powered (amongst other methods) from a coin cell or from a USB power source. The USB connection is used to program the board. When plugged into the PC, the PC sees a USB memory storage device, and a USB serial port.
The easiest way to code for the Thunderboard Sense 2 is to create an online Mbed account, and then do all your coding in the online code editor. Once you hit the Compile button, the final binary executable file gets downloaded to your downloaded files folder, and then it can be dragged into the memory storage. It immediately uploads and then begins executing. Any print statements in the code will be viewable using serial console software such as PuTTY.
The photo here shows a typical ESP32 board. Some can be powered via USB, others may accept a rechargeable battery. All of the boards are fairly similar in functionality. The ESP32 contains 2.4 GHz WiFi capability, so it is possible for the board to connect to a wireless network and then send messages to an IoT solution such as IoT Central.
Using the ESP32 board is more complicated compared to the Thunderboard Sense 2. It will entail downloading and installing ESP32 tools to the PC. If IoT capability is needed then an IoT software development kit (SDK) will also need to be downloaded, and wireless and IoT credentials will need to be entered.
The ESP32 steps won’t be described in detail here for now, because the project code still needs to be merged with the Thunderboard Sense 2 code. Once that is done, more detail will be available here.
To use the ESP32 board, the Casio calculator communications port is connected to the USART1 pins. The ADC1_6_IO34 pin on the ESP32 was used to receive analog sensor information.
What Protocols are used?
The serial protocol is known as UART. UART is similar to except the voltage levels are 0V and 3.3V, and the levels are inverted, i.e. the idle level is +3.3V. One slightly unusual thing is the Casio calculator uses two stop bits, whereas other devices are typically programmed for 1 stop bit. Aside from that, the protocol seems normal and runs at 38400 baud.
The information here and in the next few sections is useful for anyone who wants to develop code for interfacing to the calculator. It can be skipped if you just want to make use of the end project.
Two layers might be useful to describe the protocol. At a low layer, the calculator and the connected remote device send a stream of bytes in a burst called a packet. The lower layer exchanges these packets and they are acknowledged with a single-byte packet representing that the packet was received OK.
A particular set of the packets and acknowledgments is called Send38K, and another set is called Receive38K. The Send38K set is used whenever the calculator wishes to communicate some low-level data or settings or variables to the remote device. The Receive38K set is used whenever the calculator wishes to obtain data or settings or variables from the remote device.
At a higher layer, combinations of Send38K and Receive38K are used to perform valuable functions such as capture data for plotting to a chart.
The lower layer protocol is described in the EA-200 product PDF documentation. Unfortunately, some detail and parameters are undocumented.
The protocol description here can be read in conjunction with the EA-200 document.
Low Layer Protocol
Casio’s EA-200 PDF documentation describes two procedures called Send38K and Receive38K. Older calculators only used ‘Send’ and ‘Receive’ procedures.
The arrows show the packets of data that are used to form the Send38K and Receive38K procedures.
Some example packets are listed here, but the EA-200 documentation more fully explains it (some things are undocumented however).
|Name||Value or Example||Description|
|Start Indication||0x15||This single byte initiates communications and is always of value 0x15|
|CODEA_OK||0x13||This is the ‘OK’ response to the start indication, it is always 0x13|
|Always 15 bytes. The first 4 bytes are ASCII text such as :NAV or :NAL or :RAV. The N represents a send instruction, and R indicates a receive instruction. The A means ASCII format for the data about to be later sent or received. The V or L indicates Value or List for that data. The last byte is a checksum.|
|CODEB_OK||0x06||This single byte 0x06 is always used for OK responses to all instructions and data, except for the start indication|
|Data||3a,38,c8||This packet is always 3 bytes or more. The first byte is ASCII ‘:’ and the last byte is always a checksum. In this example, the remainder center byte, 0x38, is ASCII ‘8’.|
High Layer Procedures
End tasks (such as collecting sensor data for charting purposes) are performed using combinations of Send38K and Receive38K. The procedures used for sampling tasks are shown here. The content in the diagram below such as ‘1,1,2’ for the arrow marked D or ’10,-2’ for arrow E, are set-up commands. They are described in the EA-200 documentation. As an example, ‘1,1,2’ means ‘set up channel 1 for voltage measurements’. ’10,-2’ means ‘normal sensor warmup’. ’12,1’ for arrow F means ‘send data in real-time’. Some things did not make sense, such as arrow G, for which I made the code send a response arrow H, which is enough for the calculator to continue with the procedure even though it doesn’t like the response H and it issues some junk packets labeled arrow I.
Anyone with a CLAB or EA-200 could snoop the traffic and find out the correct response to send.
The real-time sampling is useful for rates of 5Hz or lower (i.e. samples every 0.2 seconds or longer). For faster sampling, the calculator expects to use a bulk non-real-time method to receive data. I’ve been unable to decipher how that works so far. I wish to solve it, because then the calculator can be used for obtaining data such as speech samples! The Thunderboard Sense 2 has an in-built microphone.
For now, the code doesn't obey the requested sample period (in arrow J in the diagram above, it is the value 0.2 seconds); it merely sends data as fast as it can in the real-time mode.
The calculator wasn’t designed for being an IoT device, so there is no protocol for this. A custom high-layer procedure was needed. I’ve called it the ‘2001’ procedure. The way it works, is that if you instruct the calculator to send a list (array) of values with the first value being 2001, then the remainder values are interpreted as being part of this new procedure.
Sending “2001, 1, 0” instructs the calculator to prepare to take a sample from the analog input. The value 1 indicates this. The last value 0 is for future expansion, it means nothing.
So, here is a Casio program that collects a sample value into a variable V, and sends it to IoT Central, and then prints the value in V to the screen:
2001->List 1 1->List 1 99->List 1 OpenComport38k Send38k List 1 Receive38k V 21->List 1 V->List 1 Send38k List 1 CloseComport38k V
The calculator also supports a variant of Python, but I don’t know how to code this in Python, or if it is even possible.
Coding the Protocols
The information here is for anyone who wants to work with the Mini Experimenter source code on GitHub.
A state machine was needed for the low layer protocol. The diagrams here show what state names were used, so that the code can be more easily searched.
Debugging the Code
The project was quickly prototyped in order to understand the communication, so the code isn’t pretty. It would be nice to re-code it one day with better separation between the low layer and high layers.
To troubleshoot, there are some debug levels in the code. If you enable a ping-pong mode (by including the line #define PINGPONG 1 then the low layer debug is shown like this:
CASIO MiniE | | | | | **COMM_IDLE** |------0x15-CASIO-START-IND----->| |<-----------CODEA_OK------------| | COMM_WAITING_INSTRUCTION |---NAV,L=1,O=1,P=1,A----------->| |<-----------CODEB_OK------------| | COMM_WAITING_DATA |--------7-STATUS_CHECK--------->| |<-----------CODEB_OK------------| | | | **COMM_IDLE** |------0x15-CASIO-START-IND----->| |<-----------CODEA_OK------------|
If you set #define HLPP 1 then the debug is simplified to this style:
CASIO MiniE | | |---S38K: 6,4------------------->| |---S38K: 7--------------------->| |<--R38K: 1----------------------| |---S38K: 0--------------------->| |---S38K: 1,1,2----------------->| |---S38K: 10,-2----------------->| |---S38K: 12,1------------------>| |---S38K: 7--------------------->| |<--R38K: 0.4981-----------------| |---S38K: 3,0.2,100,0,-1-------->|
There are some other more verbose debug levels too. Setting #define DEVELOPER 1 outputs this type of content:
waiting start indicator waiting instruction received instruction: 3a,4e,41,4c,00,02,00,00,00,01,00,03,ff,41,df text: ':NAL.........A.' instruction decoded received data packet: 3a,36,2c,30,6e text: ':6,0n' number of tokens found: 2 waiting instruction received instruction: 3a,4e,41,4c,00,01,00,00,00,01,00,01,ff,41,e2 text: ':NAL.........A.' instruction decoded received data packet: 3a,30,d0 text: ':0.' number of tokens found: 1
This project's aim was to provide a way of using Casio calculators for science projects. Mini Experimenter code was developed to communicate with Casio calculators. This opens up the possibility to capture sensor data, locally process it, chart it, and send information to an IoT platform. This blog post described a couple of possible microcontroller boards that can be used, and the protocol and the workings of the code as it stands. The project is low-cost, and perhaps could be useful for school science or math projects.
More work is needed to add functionality, such as the ability to capture data at precise sample rates, and to be able to send data in a bulk fashion for higher-speed sampling to be possible. Anyone with a CLAB or EA-200 product could help speed up the development effort by snooping the UART traffic.
Thanks for reading!