Who is here? 2 guest(s)
 Print Thread
Skywalker roaster mods
sloppyjosh
I've been doing a lot of work on this roaster. I've analyzed the communications between the roster and the controller, I can read the state of the heater, fan, and cooling fan, I'm really close on reading temperatures... I can read the data but having some issues converting it to temperature.. once I get that nailed down I should be able to pipe the data into Artisan for logging.

Happy to share any details about what I've learned about the roaster or even the data sets I've collected if anyone is interested.
 
renatoa
Wow ! sure, post here all you are happy to share.
Once the protocol is known, translating into a TC4 packet is easy, and available over USB for any external application for logging and archiving.

Do you have an USB sniffing dongle, or what spy method are you using?

Does the protocol offer a method to (over)write values on the display panel ?
Asking because the RoR is too slow, at this rate can't be used for decisions for control in manual mode... would be nice to have a faster refresh rate.
 
sloppyjosh
Here's how the roaster works from a control point of view.

All the brains are in the controller. When power is applied (that is.. when it's plugged in) both the roaster and the control panel start sending a stream of data. They're always doing this even when the controller isn't on. There is no back and forth communication protocol or anything.. just each device streaming a message to the other.

The controller connects to the roaster with a standard USB plug, however the manufacture is only using this plug for convenience. There is no USB communications going on. I soldered wires to the RX, TX, and Ground of the controller board. So I can plug those in to my logic analyzer or an arduino to sniff the data.

The roaster simply does whatever the controller says to do. Attached is an example of what the data looks like on the wire. The orange trace is 7 bytes from the roaster -> controller, the white trace is 6 bytes controller -> roaster. You can see the message preamble (the large gaps) then when the signal goes low, if it's low for roughly 625 microseconds it's a binary 0, if it's low for 1500 microseconds, it's a binary 1. The data is in LSB order.

The controller appears to send only 3 messages to the roaster. Turn the heat on/off and the duty cycle, Turn the fan on/off and the duty cycle, and turn the bean cooling fan on/off. Here are some examples of each function in the messages. The first byte is the fan speed, The third byte is the fan cooling speed, and the fifth byte is the heater.


0x41, 0x04, 0x00, 0x64, 0x46, 0xEF - Roasting Power 70 Fan 65
0x50, 0x04, 0x00, 0x64, 0x41, 0xF9 - Roasting Power 65 Fan 80
0x00, 0x00, 0x64, 0x00, 0x00, 0x64 - Cooling Fan On


The roaster sends temperature data in the first 4 bytes and a checksum in the 7th byte back to the controller.. There may be something else in there, too.. I'm not sure.. I haven't observed any correlation with the 5th and 6th bytes. They're almost always 0x00 and 0x01.


0x3, 0xf9, 0x3, 0xc2, 0x0, 0x1, 0xc2 -- Temp 50F
0x3, 0xf4, 0x3, 0x6e, 0x0, 0x1, 0x69 -- Temp 86F
0x3, 0xb5, 0x1, 0xba, 0x0, 0x1, 0x74 -- Temp 181F
0x3, 0x34, 0x0, 0xce, 0x0, 0x1, 0x6 -- Temp 244F
0x2, 0x9a, 0x0, 0x6a, 0x0, 0x1, 0x7 -- Temp  294F
0x1, 0xc9, 0x0, 0x33, 0x0, 0x1, 0xfe -- Temp 357F
0x1, 0x8, 0x0, 0x16, 0x0, 0x1, 0x20 -- Temp 429F


And this is the part I'm having trouble figuring out... If you look at the control board in the roaster, you'll see (as renatoa pointed out) they're using what appears to be a thermistor. It's being read with what I think is a voltage divider on the board.. but it's strange because instead of just one tap coming off it and going to an ADC pin on the microcontroller, they have two taps.. Each one goes through a resistor (one goes through a 2k Ohm resistor, one through a 1k Ohm resistor). I believe those values are what we see in the first and second pairs of bytes. There is an extremely strong correlation between the values of those bytes and the temperature shown on the screen. I can train a 3rd degree polynomial to predict the temp from those bytes and it is verrry close.. but the errors are still too far off.. sometimes up a degree, sometimes down two degrees, sometimes it'll be right on it.. I just can't seem to sort out the relationship between those bytes and the temp.

I have a data set of about 1600 values for bytes 1,2,3,4 and the corresponding temperature shown on the screen. I collected that by capturing the data from the roaster using a logic analyzer, extracting the binary, then replaying each message back to the controller. I then record the value shown on the screen for each message. I think part of the reason my regression has the errors it has is because the controller is only showing me integer values so I'm losing some information there.

I think I'm REALLY close to a logging solution, and I think a control solution could be implemented with a bit more effort. I think if you were going to control it externally, the way to go would be to just emulate the controller completely or just replace their controller with a TC4+.. I think you'd have to replace the thermistor with a thermocouple as well though.

I've attached a file fullrealdataints.txt If anyone wants to take a crack at figuring out the relationship between the first two values (the first two bytes and the second two bytes converted to integers) and the last value (the temperature in Fahrenheit) then be my guest :) If you crack the code let me know.. This is the last hurdle to having logging implemented.
sloppyjosh attached the following file:
fullrealdataints.zip [5.36kB / 332 Downloads]
sloppyjosh attached the following images:
messages_1.png controllerboard2.jpg

Edited by sloppyjosh on 12/03/2023 9:44 AM
 
renatoa
Great findings, you spent some time on this spy job !

So the protocol is a proprietary binary stream, not standard serial ?

Did you figured if the temp values are proportional with voltage on the probe, or reversed?
This could tell us the sensor type, RTD or NTC.
The connection description, with two resistors, suggest me a differential input to ADC, as is used for a Pt100 adapter/amplifier, see attached image.

An alternative to sending data elsewhere, would be keeping the whole self contained, by replacing the panel with a Raspi running Artisan, and a small piece of code as interface between the roaster protocol, and a known protocol for Artisan, TC4 or Modbus. Just a thought...
~~~
renatoa attached the following image:
image_2023-12-03_174621444.png

Edited by renatoa on 12/03/2023 10:19 AM
 
sloppyjosh
The readings from the roaster are inversely proportional to the temps but I haven't put a meter directly on the probe.

I used a 4th degree polynomial and got it working pretty well. I ran a preheat cycle and it the values output by my Arduino seemed in line with the controller. The controller applies some smoothing so it's kind of difficult to get a direct 1:1 agreement but it looked really good.

I just need write the code to indicate the status of the fan and heater, put it in the correct format for Artisan and give it a go.
 
renatoa
You are moving faster than I can follow you Grin
Do you have any idea what processor is that... JS32...
The other chip TM1640 is the displays driver, got it.
 
sloppyjosh
It's a js32t031f5s7 the data sheet is online.. in Chinese only.. Google translate works well on it though.

The data lines are connected to the UART0 RX and TX lines but I think they must just be bit banging the output. That's how I drive the controller to correlate the values to the temp on the display.

Unfortunately, the chip in the roaster doesn't appear to have any real identification on it.

It says FMD N3hWIKH

FMD is a chip manufacturer that makes a few microcontrollers but I couldn't find any data sheet that looked like it matched the chip itself.
sloppyjosh attached the following images:
screenshot_20231203-150852.png screenshot_20231203-151334.png

Edited by sloppyjosh on 12/03/2023 2:17 PM
 
sloppyjosh
Roasted 300g of Coffee Coral Ferdelance using profile 022 on the skywalker... Here's what I recorded in Artisan. The roast came out to about a City roast. With a loss of 12%. I usually like them into City+ or Full City.. Never had this blend before though so who knows.. maybe I'll like it.

I have very little experience with artisan.. so I have no idea how this profile looks.. You tell me haha.


That said.. My SkywalkerSpy works!
sloppyjosh attached the following image:
updatedfirstroast.png

Edited by sloppyjosh on 12/04/2023 10:56 AM
 
jwmelvin
This is great! Thank you for doing this work and sharing it here. It makes me much more likely to experiment with this roaster.
 
renatoa
It looks ok as is, close to the classic approach that advise having after dry end a continuous descending RoR (Delta BT), and avoid as much as possible flat areas (as minute 3 to 5), or even worse, a raising trend of the delta graph.

Something like the red line I sketched on top of your graph.

So the power reduction should start earlier, about minute 4, and be done in many smaller steps, at last two steps 70-60-50 instead the sharp 70-50 at 170C done by auto logic. Smaller steps for the fan too.

Sky(walker) is the limit now for experiments.
We have rules to know how many we broken when the last coffee we roast is memorable, and we are unable to reproduce the roast again Grin

Wondering how long will take until Darth Vader appears ...
renatoa attached the following image:
image_2023-12-05_112754837.png

Edited by renatoa on 12/05/2023 3:31 AM
 
sloppyjosh
Vader is on the way. Grin I already have all the pieces..

I need to better understand how to get Artisan to talk to the Arduino. Currently, I have artisan calling a python program that asks the Arduino for the data. I don't think this approach will work for artisan to control it though. I believe you had mentioned using TC4 messages.. that may work.. If you have any other ideas/references for this let me know.. I don't really know artisan that well.
 
jwmelvin
This may help understand how Artisan talks to a TC4: https://github.co...tisanQ_PID
Edited by renatoa on 12/05/2023 2:07 AM
 
renatoa
As @jwmelvin posted above, just an USB/serial stream implementing some of the TC4 commands, not all.
The minimal set of commands should contain: READ, for data acquiring, and OT1/OT2 for HTR/FAN control.
However, at the start of the roast Artisan sends some config commands, that could of interest for you to know how to tailor the READ command response packet. These commands are:

- CHAN;2100 or CHAN;1200 - instructs you about the order of temperatures in the packet sent by you as reply to READ command. 1 means ET, 2 means BT
For ET you can post same value as BT or zero.
You should ack this command sending back #CHAN
If not ack Artisan will continue spamming you with CHAN commands interlaced with READ commands.

- UNITS; followed by C or F - this command tells to TC4 which unit will use Artisan, so all data sent as response to READ command should be converted by your box to C or F accordingly. This command should not be ack by sending back something

- FILT;xx;yy;zz - this command immediately follows UNITS, you can ignore, is about filtering coefficients for rolling average of temperatures and rate of change.

UNITS and FILT immediately follows #CHAN ack sent by you, and will never come back until they are changed in Artisan, next roast. They can't be changed in the middle of a roast.

Response packet to a READ command looks like:
AT;ET;BT;T3;T4;HTR;FAN;SP ; where
- AT = ambient
- ET/BT - could be reversed, according to CHAN command
- T3/T4 = optional other two temperatures
- HTR = actual heater value, to confirm the change by OT1 command
- FAN = actual fan value, to confirm the change by OT2 command
- SP = set point for a pid profile, ignore, set to zero
Edited by renatoa on 12/05/2023 2:41 AM
 
renatoa

Quote

sloppyjosh wrote:
...
The roast came out to about a City roast. With a loss of 12%.
...


This is line with to my roasts notes, beans looking as medium roast, but the weight loss is characteristic to a light roast...
And they look not so well developed, beans are still smaller than I know them from a mixed convective-radiation roast.
This could mean the IR is too powerful and penetrate only the surface, letting the inside less developed.
Should experiment more with Manual mode, using lower power and longer roast times. And maybe more air.
As is now, a roast done in the 6-7 minutes ballpark, looks like a fluid bed roast, minus the convection, thus somewhat forced, imo.
 
Robotic Kitten
This thread needs more upvotes. Great job @sloppyjosh

Quote

just an USB/serial stream implementing some of the TC4 commands, not all.


Are there any BLE roasters which Artisan supports? I wouldn't mind a wireless connection to the roaster Grin Can't wait for my roaster to arrive.
 
sloppyjosh
Full control is working. Haven't done a roast yet but I was playing with the PID controller just for fun. There's still a few quirks to work out but overall I'm pleased with it.
sloppyjosh attached the following image:
2023-12-05_17_11_41-_artisan_2100_paolo_scimone_coffee_consulting_release_sponsor.png
 
Robotic Kitten

Quote

sloppyjosh wrote:

0x3, 0xf9, 0x3, 0xc2, 0x0, 0x1, 0xc2 -- Temp 50F
0x3, 0xf4, 0x3, 0x6e, 0x0, 0x1, 0x69 -- Temp 86F
0x3, 0xb5, 0x1, 0xba, 0x0, 0x1, 0x74 -- Temp 181F
0x3, 0x34, 0x0, 0xce, 0x0, 0x1, 0x6 -- Temp 244F
0x2, 0x9a, 0x0, 0x6a, 0x0, 0x1, 0x7 -- Temp  294F
0x1, 0xc9, 0x0, 0x33, 0x0, 0x1, 0xfe -- Temp 357F
0x1, 0x8, 0x0, 0x16, 0x0, 0x1, 0x20 -- Temp 429F


And this is the part I'm having trouble figuring out... If you look at the control board in the roaster, you'll see (as renatoa pointed out) they're using what appears to be a thermistor. It's being read with what I think is a voltage divider on the board.. but it's strange because instead of just one tap coming off it and going to an ADC pin on the microcontroller, they have two taps.. Each one goes through a resistor (one goes through a 2k Ohm resistor, one through a 1k Ohm resistor).


Any chance you could post the full picture of the board and indicate where the "thermistor" is connected to?
Can you also confirm if the thermistor resistance increases or decreases with the temperature?

One hypothesis: it is an Negative Temperature Coefficient thermistor and voltage divider is: 5v -- R1 -- Thermistor -- R2 -- GND and the two taps are connected to thermistor's terminals. Then the 1st integer is an ADC value for R1/Thermistor tap and the second value is Thermistor/R2 tap (closer to the ground). The higher the temp -> the lower thermistor's value -> the lower both taps and closer to each other in value.
Edited by Robotic Kitten on 12/05/2023 6:08 PM
 
sloppyjosh
Here's a close up of the board. The thermistor is the two connections by the blue arrow. I believe the orange connection has a filter cap (C5) between the line and ground.

I still haven't taken the board back out to check the thermistor resistance. I'll try to do that tomorrow.
sloppyjosh attached the following image:
pxl_20231129_1727123113.jpg
 
sloppyjosh
Code is here:

https://github.co...kerRoaster
 
renatoa

Quote

Robotic Kitten wrote:

This thread needs more upvotes. Great job @sloppyjosh

Quote

just an USB/serial stream implementing some of the TC4 commands, not all.


Are there any BLE roasters which Artisan supports? I wouldn't mind a wireless connection to the roaster Grin Can't wait for my roaster to arrive.


Depends if the BLE on the device running Artisan implements BT serial.
 
renatoa
From github project

Quote

For the Fan and Heater, duty cycles increment by 5.
Sending other values will be ignored.


So I can't have 1% control heater precision using the protocol ?
If I send 48% will be ignored ? Either 45 or 50, nothing inbetween ?
 
renatoa

Quote

Robotic Kitten wrote:

One hypothesis: it is an Negative Temperature Coefficient thermistor and voltage divider is: 5v -- R1 -- Thermistor -- R2 -- GND and the two taps are connected to thermistor's terminals. Then the 1st integer is an ADC value for R1/Thermistor tap and the second value is Thermistor/R2 tap (closer to the ground). The higher the temp -> the lower thermistor's value -> the lower both taps and closer to each other in value.


The divider is 5V -> R15 (30k) / NTC (5k) - Gnd.
Thus, the voltage on NTC should be about 5V * 5k / (30k+5k) = 0.7V ballpark, at ambient temp.
If this voltage is measured by a 12 bit ADC (0...4095), corresponding to a 3.3V input voltage range, then the ADC value of 0,7V would be 887, somewhere in the dataset post by sloppyjosh.
The two resistors coming from the processor, R25 and R16, both connects to the NTC common point of divider.
No idea what could be measured on two separate paths, connected to same point...
Maybe one path is connected by other trace to other onboard sensor, to implement an ambient temperature compensation.

Plotting the sloppyjosh data, we have that attached graph. The gray curve is the display temperature.
The other two plots looks both as different parts of a typical NTC graph, as seen in the "Linearization..." picture, which is a plot based on Steinhart Hart_equation: https://en.wikipe...t_equation

An Arduino library implementing this equation could be found here: https://github.co...thermistor
There are three parameters needed: Nominal resistance at 25 ºC (~5k), thermistor's beta coefficient, Value of the series resistor (30k). The unknown is the beta coefficient, I think can be found by reverse eng from the sloppyjosh data.

~~~
renatoa attached the following images:
image_2023-12-06_194810146.png skywalker_adc_temp.jpg

Edited by renatoa on 12/06/2023 12:33 PM
 
Robotic Kitten


Thanks for the great writeup!
 
sloppyjosh

Quote

Robotic Kitten wrote:



Thanks for the great writeup!


No problem! I'm just over here having fun smile
 
sloppyjosh

Quote

renatoa wrote:

Quote

Robotic Kitten wrote:

One hypothesis: it is an Negative Temperature Coefficient thermistor and voltage divider is: 5v -- R1 -- Thermistor -- R2 -- GND and the two taps are connected to thermistor's terminals. Then the 1st integer is an ADC value for R1/Thermistor tap and the second value is Thermistor/R2 tap (closer to the ground). The higher the temp -> the lower thermistor's value -> the lower both taps and closer to each other in value.


The divider is 5V -> R15 (30k) / NTC (5k) - Gnd.
Thus, the voltage on NTC should be about 5V * 5k / (30k+5k) = 0.7V ballpark, at ambient temp.
If this voltage is measured by a 12 bit ADC (0...4095), corresponding to a 3.3V input voltage range, then the ADC value of 0,7V would be 887, somewhere in the dataset post by sloppyjosh.
The two resistors coming from the processor, R25 and R16, both connects to the NTC common point of divider.
No idea what could be measured on two separate paths, connected to same point...
Maybe one path is connected by other trace to other onboard sensor, to implement an ambient temperature compensation.

Plotting the sloppyjosh data, we have that attached graph. The gray curve is the display temperature.
The other two plots looks both as different parts of a typical NTC graph, as seen in the "Linearization..." picture, which is a plot based on Steinhart Hart_equation: https://en.wikipe...t_equation

An Arduino library implementing this equation could be found here: https://github.co...thermistor
There are three parameters needed: Nominal resistance at 25 ºC (~5k), thermistor's beta coefficient, Value of the series resistor (30k). The unknown is the beta coefficient, I think can be found by reverse eng from the sloppyjosh data.

~~~


I believe it's using 10-bit ADCs, all the values are within that range.

Additionally, the temps we see are derived from both the values sent in the data. It's not just ignoring one, or one is something else we don't understand, or a completely different sensor, etc.. I have another script for replaying values to the controller to see what the temp will display. Through manual experimentation you can immediately tell both values are used to derive the temp.

When you sort the data by the values of either the first or second column, you can see what I mean. Consider these rows, they all have the same value for the first.. 1011


1011,820, 102
1011,831, 98
1011,832, 98
1011,842, 96
1011,845, 95
1011,852, 93
1011,857, 91
1011,858, 91
1011,861, 91
1011,870, 87
1011,873, 87
1011,876, 86
1011,879, 84
1011,882, 84
1011,883, 84
1011,890, 80
1011,891, 80
1011,894, 80


But now we can sort by the second row and see the same thing. All with 2nd value 29.

309   29   410
312   29   408
317   29   406
322   29   404
326   29   402
328   29   402
331   29   401
340   29   397


This occurs at low temps for the first value, and high temps for the second one..

Of course, these may not be the raw values from the ADC.. maybe they've been transformed somehow. but it just doesn't make sense.

Quote

So I can't have 1% control heater precision using the protocol ?
If I send 48% will be ignored ? Either 45 or 50, nothing inbetween ?


This is correct. I tested by setting something low like 25 then going to 78. Nothing happens. But if you go to 75 you'll see the heater get brighter.

I was thinking about collecting another set of data.. I need to do it anyway.. at least for some higher temps beyond what's in the data set.. The model is very much overfit to the dataset and won't generalize well.. if you go beyond, say 435F things are going to get strange really fast. But I was considering putting a second probe inside the machine and logging the real temp reported by that probe. Maybe even running a roast with it like this, too. I have a few probes, but would probably use the bare thermocouple as I think it'd have the fastest response time. I would expect the Skywalker's probe would lag behind just a bit in comparison but I'm curious to see what it would look like. I find it interesting that on the two roasts I've done in it, I hit FC about 20 degrees too soon.
Edited by sloppyjosh on 12/06/2023 10:17 PM
 
Jump to Forum: