bigtreetech / BIGTREETECH-S42B-V1.0

The closed-loop drive is to feedback the rotation angle of the stepping motor to the control panel, compare the distance that needs to be rotated with the distance of the actual rotation, calculate the error value, and then compensate, so as to prevent the problem of multi-step and lost step. The closed-loop drive can completely overcome the lost step of the open-loop stepping motor, and can also significantly improve the performance of the motor at high speed
108 stars 53 forks source link

Error in OLED initialization code #16

Open jmdhuse opened 3 years ago

jmdhuse commented 3 years ago

In the file oled.c, where the clock divide ration and oscillator frequency are initialized with the 0xD5 command. The parameter in the file is "80", but I think it should be the hex value "0x80". This might address some of the display instability issues.

Quas7 commented 3 years ago

Interesting finding. Expected for D5h is a 8-bit value representing [3:0] 4-bit "clock divide ratio" and [7:4] 4-bit "Oscillator Freq." 0d80 = 0b 0101 0000 = ~320 kHz clock and divider 1 0x80 = 0b 1000 0000 = ~380 kHz clock and divider 1 (this would be the default setting)

I experienced many display issues before updating the firmware via this repo. But, I still have display issues after 20h printing.

Therefore, I will try to measure PWM frequency of the motor drivers and stay away from the harmonics for the clock+divider setting. I did not find the magic number for the PWM frequency in the source code yet. Maybe someone else has more luck/skill?

adding the relevant datasheet informations from p.43 here:

image

10.1.16 Set Display Clock Divide Ratio/ Oscillator Frequency (D5h) This command consists of two functions: • Display Clock Divide Ratio (D)(A[3:0]) Set the divide ratio to generate DCLK (Display Clock) from CLK. The divide ratio is from 1 to 16, with reset value = 1. Please refer to section 8.3 for the details relationship of DCLK and CLK. • Oscillator Frequency (A[7:4]) Program the oscillator frequency Fosc that is the source of CLK if CLS pin is pulled high. The 4-bit value results in 16 different frequency settings available as shown below. The default setting is 1000b.

SSD1306-SolomonSystech.pdf

Quas7 commented 3 years ago

Jan pointed out, that 187.5kHz might be the PWM frequency. https://github.com/bigtreetech/BIGTREETECH-S42B-V1.0/issues/17

Therefore, staying away from 375kHz would be a good idea to get stable communicaiton but the default setting is hitting the first straight harmonic (380kHz +/-).

caesar1111 commented 3 years ago

Hi and sorry to ask this silly quesiton, but is there a description in how to connect the S42B to the computer? I not an expert in programming microcontrollers, but stumbled across the problem you described on two fo my three controll boards I just recieved recently. I will try the 0x80 default setting and everything is already compiled, so I just need the description on the "hardware part" of how to connect the controller...Thks in Advance

Quas7 commented 3 years ago

sure, no problem @caesar1111 . I explained the hardware setup here https://github.com/bigtreetech/BIGTREETECH-S42B-V1.0/issues/3

It might be better to change the OLED to something 25% faster or slower than 0x80 as this is hitting the PWM frequency as a possible source for interference.

caesar1111 commented 3 years ago

@Quas7 thks a lot, I just order this programmer: https://www.amazon.de/gp/product/B086TWZNMM/ref=ox_sc_act_title_1?smid=A1X7QLRQH87QA3&psc=1 as for the requency.. should I go with the 0d80 you mentioned above? and just to be sure, you mentioned "SWCK, SDO, GND" in your description. In the pinout there is just the SWDO, so I will go with this mapping: S42B pin -> Programmer PIN: SWCK -> SWCLK SWDO -> SWDIO GND -> GND 3.3V -> 3.3V will post as soon as I have the programmer and had a chance to flash the board... my SK-Go² is waiting for some torture tests on the S42B. Spare belts are ready :)

Quas7 commented 3 years ago

The programmer looks good and even supports the original ST flashing software (not all clones do that).

If you power the board from another source, I recommend not to connect 3.3v (in theory, the stronger voltage source kills the weaker one or just generates heat). SWDIO is correct (Serial Wire Data Input/Output) - it is just named differently on the silk screen due to little space, I think.

I would try the lowest frequency range first with 0x00 (280kHz +/-). This whould be centered somewhere between the harmonics of the PWM. If I find time, I will build a small coil probe and try to measure the actual frequency peaks with an Osci or a nanoVNA.

I run S42b only on my extruders as it keeps the motor very cool compared to just pushing current through it with open-loop stepper drivers. For other drivers I did not see the benefit - if I miss steps, there is something else wrong. And even with S42b the timing will get a hit as the central processing unit still does not know that there was a deviation so there will always be a small artefact in the print. On top, I do not need travel moves beyond 500mm/s and for print moves the hotend is still the speed limiting factor in my setups (did not yet try volcanos though). But enjoy torturing your SK-Go2 and maybe give some feedback, if you actually made anything move faster or more precise than with the stock TMC2209 on 1.5A :)

nhabes79 commented 3 years ago

Interesting discussion. I too can't stand the instability of the OLED screens. They simply aren't useful. I have found that when my printer is powered down and I have the OLED powered through an ST-link or UART, they are super stable. No issues at all.

I actually do have these motors on my y and x axis. I like to do a lot of stripes in my TPU prints, so I'm changing colors a lot. I'm a bit heavy handed and sometimes bump the print head when I am changing colors. Print is over right then and there. Also, I recently got a delta printer. Love it. Changing colors on it is a nightmare. I have about a 50% chance of knocking the print head out of alignment.

I also like to print fast. Sometimes this causes the print head to come out of alignment.

Anyways, I'm hoping these motors fix the problem.

I'm not a programmer and most of the programming vocabulary goes right over my head. I am curious though if you all are having success changing the firmware for S42B. I was able to find something online that showed me how to make VScode/platformio compile as a hex file. I use ST utility to upload the firmware to PCB, but nothing ever seems to change. First of all, the firmware I compile is 85KB while the stock is only 73KB. That seems odd considering I've only been changing the PID values. Secondly, when I use the ST utility to compare the stock firmware to a firmware I've compiled, it is wildly different. Doesn't make much sense to me if I'm only changing a couple of numbers.

The only way I've been able to successfully change the PID values is through the UART connection and using BTT's serial port assistant. That works, but that doesn't have all the options that you all are talking about with the OLED screen issues. Also, while I'm thinking about it, if I change the PID values in the firmware, compile and upload, then check them through the UART connection and BTT's serial port assistant, the PID values are still the same as they were before. It's weird. Nothing changes when I compile a new firmware.

Quas7 commented 3 years ago

Just thinking, maybe it is easier to enable "advanced pause" in Marlin and do a home-after-change? Normally, the homing precision is better than 0.05mm with standard mechanical endstops (short lever ones). A repeatability test can be enabled in Marlin as well to verify that for Z-probing.

I have also bought last week an ultra cheap delta printer (FLSUN Q5) and I love it as it is really ultrasilent after a few mods (fans, hotend, UART steppers, BMG extruders, etc.) but as it is a bowden I do not touch the print head for changing filaments at all and I installed a TL Y-splitter for automatic 2 color prints. But I have to do more testing this weekend to get some statistics for possible errors of that setup first.

Regarding your flashing issue. I do not get a hex-file after compiling this repository but a binary and this is 30.872 bytes big. That should also be the default for this repository, I think. As nothing changes for you but the upload seems to be valid... without any offence... did you check the time stamp on your hex files after compiling? I just want to make sure, you really flash a freshly compiled hex and not a leftover file from the repo itself. ;)

My binary compiled via vs code + platform.io is located in \firmware\S42BV1.0.pioenvs\BIGTREE_S42B_V1_0\firwmare.bin

And second thing... you do change these initial values in main.c, right? line 314 to 316: int16_t kp=30;
int16_t ki=10;
int16_t kd=300;

and it seems, that for the MKS servo42b (very similar product) there are units sold with a controller protection. https://github.com/makerbase-mks/MKS-SERVO42B/issues/17 Maybe, some batches of S42B come also protected in this way?

AbeFM commented 3 years ago

@Quas7 thks a lot, I just order this programmer: https://www.amazon.de/gp/product/B086TWZNMM/ref=ox_sc_act_title_1?smid=A1X7QLRQH87QA3&psc=1

I just got that one, or one just like it - and am having really mixed luck with it. Some times it'll connect, sometimes it drops. I don't trust this controller and I don't trust the STLink and it's been a LOT of debugging. I'm looking forward to seeing how that goes for you.

The first time I tried programming it powered by the dongle (and DISconnected from the printer by pulling the white cable) it didn't work, and plugged into printer it didn't work until I fed +5V on the 5V line. Today, it only works powered from the dongle and not when powered from the printer.

Perhaps a seperate thread for general programming issues makes sense so as not to clutter firmware issues.

@nhabes79

I use ST utility to upload the firmware to PCB, but nothing ever seems to change. First of all, the firmware I compile is 85KB while the stock is only 73KB. That seems odd considering I've only been changing the PID values. Secondly, when I use the ST utility to compare the stock firmware to a firmware I've compiled, it is wildly different. Doesn't make much sense to me if I'm only changing a couple of numbers.

I was using the same process this morning. My firmware was 30,872 bytes, like the one @Quas7 posted. I couldn't get stuff to upload from VSC/PIO but I can't tell with all my connection issues what's going on. I'm getting .bin files, BTW. I'm also hoping to use this to prevent occasional skips on the Y-axis - I've set the speeds and accels so low it's really effecting my printing.

Are you hand-calculating the checksums? I found a calculator, tried to write a spreadsheet, but I think I'll have to get into VBA or something to get the checksums and was figuring I'd just use the online calculator. :-\

Re: Changing filament: You should be able to do that with just g-code commands, or through the menus, you can set up load and unload procedures where you shouldn't have to tweak the extruder directly, I've got this on both bowden and direct drive units... And even so, I don't knock the head around as long as it's locked in position... Perhaps a Delta would be less stable?

Lastly: I added a block RIGHT after the includes:

//Set gain constants here. OEM defaults are 30/10/200

define kP_Gain 30

define kI_Gain 5

define kD_Gain 200

and edited 314-316 to be: int16_t kp=kP_Gain; //was: 30 int16_t ki=kI_Gain; //was: 10 int16_t kd=kD_Gain; //was: 250

I just don't like scrolling.

Quas7 commented 3 years ago

@AbeFM I can feel your pain with the programmers. I have various stlink clones, an original stlink v3 and a bag full of converted black magic probes (you can convert a stlink clone or a blue pill board) as well as an original black magic probe. In my experience, all of them work fine but the clones not always at full speed at with all tools (e.g. ST software).

For uploading with stlink clones I noramllyy use st-flash: https://github.com/stlink-org/stlink But you have to install MSYS2 MinGW (linux in windows) to use it.

The problem with the S42B is mainly the PWM output stage, if the board is "enabled" (normally it is active low!). You can try to set motor current = 0, enable active high (stays off, when unconnected) or remove the motor voltage supply from the JST connector.

nhabes79 commented 3 years ago

Quas7 - Funny. I just got the FLSUN QQS. Changed out the board for an SKR 1.4 turbo with 2209s. Loud as can be. Easily my loudest printer and my corexy and cartesian also used to run the same setup and you could barely hear them. I have to learn more mechanically about the delta to see what is causing all the racket. But man, do I ever love the speed of the delta.

I've always used Cura as my slicer. Works good enough for me. I just use its function to pause at a certain layer and move the head away from my print. I manually pull the filament out and change it. I don't touch the print head at all for my delta to do this (bowden setup), but the print head slightly moves almost every time no matter how careful I am. This is what originally got me on the idea of these closed loop setups. I like your idea of advanced pause feature, but I'm afraid I would still run into the same issue. Also realize I'm doing this with TPU. Sometimes I have to push hard to get the new filament pushed into the hotend. It's uncommon for me to bump my CoreXY or cartesian, but it still happens (probably 10-15%). I've already noticed that the closed loop function still works when my printer is paused. I've pushed hard on my print heads for both of those printers and it snaps back into place - waiting patiently for me to change the filament. :) This is obviously a "me" issue. I'm heavy handed and I'm just looking for an extra "crutch" to help me out on these filament changes. Especially once I convert my delta.

I changed something in VS code or something in platformio.... I can't remember. Somehow, I got it to compile into a hex file. I thought I had to do this because the S42B firmware is hex. I didn't know I could compile it as a binary and just use it that way. That would be a lot easier.

Yes. I check the timestamps on my files. lol. That's one of the first things I learned when I first downloaded this software to compile marlin. Learned that the hard way. I'm definitely uploading my latest compiled hex files, but now I'm super curious to try out using binary to see if that works. I'm tired of doing all the checksum calculations using BTT's serial port assistant.

Yes, the lines you mentioned in the firmware (314-316) - those are the ones I've been changing with no luck. Nothing happens. We'll see when I try with making a binary file.

AbeFM

Yes, I've been hand calculating the checksums (just learned what that was the other day). I too thought about making a spreadsheet, but things get more complicated, at least for me and the time I want to spend, when it comes to adding up the negative numbers. And that one took me awhile to figure out (especially the D value if you want to try something above 255). You have to use the negative value (didn't know that was a thing when I first looked at this) for A2 (A0 or A1 for P and I), then add it to 05 and your new value you want to put in for P, I or D. However, it all has to stay in 8 bit form, so the checksum can't be bigger than 2 characters. In that case, you need to split up your new P, I or D value into 8 bit form and add those two numbers separately. Took me way too long to realize that one. I have a feeling though I'm just saying things you all already know. Hexidecimal is all new to me.

The thing you did with setting the gain constants, do I have to do that to change them? I tend to just leave my VScode open to the spot where I want to change. Really no scrolling involved.

Yeah, I figured I could use gcodes to do a color change, but I found a way that works for me. Every time I've tried to setup something via gcode, something goes wrong. Like after a color change the print head will go back to printing but push out another 50mm of plastic first before restarting and thus ruin my print. I could keep trying to go down this route, but I like what I do. For the most part, it is easy. I could try sending the printhead to home to change my filament, but its extremely hard for me to do on my corexy at the home position. The cartesian would be easier, but I guarantee I can still bump it out of place. Most of my color changes go smoothly. Sometimes things just get stuck and I have to force it a bit more to get through the extruder (Hemera on my corexy and bmg on my delta and cartesian). That's usually when I bump it. As for the delta, No matter what, I'm going to bump it. Doesn't matter where I tell it to home.

Quas7 commented 3 years ago

@nhabes79 You can try to flash my compiled binary from this thread in case you still run into issues with your compiled one. https://github.com/bigtreetech/BIGTREETECH-S42B-V1.0/files/5210515/S42B_fw_P30_I10_D200.zip My default was P30 I10 D250 - I hope, that is also yours. If you need other values to verify, let me know.

And I just noticed, that all this checksum magic is maybe needed because the devs have been aware, that there is an EMI issue for an enabled drive stage. ;)

And regarding the homing thing. The trick would be to home after changing the filament. No matter how hard you bumped it during filament change, it would just resync the coordinates and know where to start printing again. I think, that is one of the advanced pause features of marlin that can be enabled (home after pause or something like that).

Quas7 commented 3 years ago

In case, you want to temporarely convert your cheap stlink v2 clones to a blackmagic probe: https://github.com/sakana280/stlink-tool Worked for me right out of the box. Powercycling removes the BMP upgrade. To get it working in platform.io: https://docs.platformio.org/en/latest/plus/debug-tools/blackmagic.html

nhabes79 commented 3 years ago

Ok, first of all, I don't know what any of what you said here means:

And I just noticed, that all this checksum magic is maybe needed because the devs have been aware, that there is an EMI issue for an enabled drive stage. ;)

That's unfortunately above my pay grade. I get into the weeds quick when I try to get information out of computer stuff/programming stuff message boards. Very quickly I have no idea what anyone is talking about. I also don't know what a blackmagic probe is or why I would want to convert my ST Link to one. I also don't know what powercycling is that will remove something called a BMP upgrade.

No worries. Maybe someday I'll look up what this all means.

So, the PID values you have in your firmware file are the stock ones. I'm truly amazed that you got that to work. Having my I value above 1 is an imediate failure. Didn't matter what my P or D values were. Have a look at the pictures below. These were all done on my cartesian printer. The one on the left is with TMC 2209s in open loop. The one in the middle is with the S42B closed loop with stock PID values. The print quality is horrendous. The overshoot is super obvious. The layers can't even stack on top of each other. The one on the right is with my PID values that I entered in hand calculating the hex numbers and using the serial port assistant to do so. IMG_7400 IMG_7401 IMG_7402

Now, here is where it gets interesting. I changed my platformio back to creating bin files instead of hex. I remembered now, you have to make an edit in the main.py file.

mainpy file

Anyway, I went ahead and compiled my own binary file. Ended up being the same size as your binary file. All good. I used STM32 ST-Link utility to flash it to the S42B. It asked me if I wanted to start at a specific address 0x08000000. I have no idea what that means. I just clicked ok. I then checked the PID values in the serial port assistant. Looked weird.

Then I decided to flash your firmware to my S42B and check the PID values in the serial port assistant. This picture below is exactly what I got whether I used your binary firmware or mine. PID values from binary firmware

If this is what you are using, I don't think your I value is 10 either. I think yours is like mine and is set at 1. Why is P at 040 and D at 025? I have no idea. Either way, I'm back to square one and will have to make PID adjustments through the serial port assistant instead flashing firmware.

Unfortunately, all these tests have now completely jacked up one of my S42B boards. I tried to flash back to the stock firmware (the file called ITEM.hex in the S42B files) and now I get this if I try to check my PID values. the motor still works, but I can't read any of the values on my board nor will it allow me to change them. If you have any idea on what I have to do to flash this back to stock so I can use the serial port assistant again, it would be much appreciated. I don't have to go the route of flashing firmware to change my PID values. The serial port assistant was working fine before even if I had to hand calculate the values. I'm fine going back to that.

jacked up S42B

Quas7 commented 3 years ago

No problem @nhabes79. Obviously, you do not need a blackmagic probe or anything fency as your clone is working with the ST link software (many stlink v2 clones do not work this way). These PID values are stepper motor specific and I use my S42B only for the extruder where I have naturally a crazy high dampening on the movment (geared extruder and pushing filament). Therefore, my "I" values can stay stock.

I think, the flashing you do is actually not erasing the part where these values are stored. Maybe it helps if you do a full "chip erase" before flashing? image

caesar1111 commented 3 years ago

Hi, good the read up on the article, since I hit a similar wall while tuning my SK-Go² (corexy) now running the S42B for X and Y: caesar0. As you can see, the overall quality is not to bad, but: caesar1 I have a severe overshooting on the corners. It does not matter what material (black is PLA, organe is PETG), no matter what temperature, acceleration or print speed. So if you are now telling me that this could be related to the PID setting in the firmware of the S42B, at least this leave me with another thing to check up. Since I am still waiting for my programmer to arrive, I cant really start the testing, but what would help for a fast feedback is a precompiled firmeware which is adressing the OLED frequency and the PID issue, just to start into the right direction..... ....will come back as soon as I have the programmer...

Quas7 commented 3 years ago

@caesar1111 are you sure, that this is really XY is overshooting and this is not just overextrusion because of low Jerk/Acceleration at corners? This overextrusion is typical for FDM, if there is no linear advance (pressure advance) enabled and calibrated. If you are slowing down at corners the molten plastic is not following a linear characteristic (it is lagging behind) as the mechanics do.

Did you try with "open loop" (switch 3), if you get the same?

caesar1111 commented 3 years ago

@Quas7 its a good point. I didnt have the issue when I was running the printer with 0.9 steppers and TMC2209 for X and Y... but I was also changing to Volcano hotend in the process of migrating. So LIN_ADVANCE is not switched on so far, but I was playing around with jerk (or nowadays #define JUNCTION_DEVIATION_MM 0.01) and the acceleration:

define DEFAULT_MAX_ACCELERATION { 2500, 2500, 50, 2500 }

define DEFAULT_ACCELERATION 2000

define DEFAULT_RETRACT_ACCELERATION 2500

define DEFAULT_TRAVEL_ACCELERATION 2500

starting the acceleration at 500 and went up to 2500 but this didnt change anything.... 120465862_10218373419035389_2853584192811183335_n ....so next stop: enable and tune in linear advance.

Quas7 commented 3 years ago

Ok, with a volcano this non-linear effect is even more pronounced. BTW, the testcube is maybe not the best object to test for acceleration and jerk as you need some free distances to get to full speed first. TeachingTec goes over the basics well enough, I think: https://www.youtube.com/watch?v=Mnvj6xCzikM&t=933s&ab_channel=TeachingTech https://www.youtube.com/watch?v=rp3r921DBGI&t=123s&ab_channel=TeachingTech

nhabes79 commented 3 years ago

No problem @nhabes79. Obviously, you do not need a blackmagic probe or anything fency as your clone is working with the ST link software (many stlink v2 clones do not work this way). These PID values are stepper motor specific and I use my S42B only for the extruder where I have naturally a crazy high dampening on the movment (geared extruder and pushing filament). Therefore, my "I" values can stay stock.

I think, the flashing you do is actually not erasing the part where these values are stored. Maybe it helps if you do a full "chip erase" before flashing?

Ok, I have to laugh, but that's exactly what I did that has completely messed up my S42B board (full chip erase, then flash with stock ITEM.hex firmware). No idea why. I have some new S42B boards coming in, just a shame I can't adjust this particular one anymore. Everything else on it still works. It still runs the motor fine in my printer, I just can't adjust the PID values now.

Quas7 commented 3 years ago

@nhabes79 There is one more thing to try as I ran into this for an MKS servo42b recently. In settings decrease the communication speed to 240kHz and set it to "Software System Reset" image

Than check the Option Bytes. image

All flags shood look like in this screenshot (readout from a S42B): image

Especially the WDG_SW has to be enabled, otherwise it will reboot continously. Also, all pages should have "No Protection". If there is a mark it will show "Write Protection". I think, platform.io will still give you a "success" but the actual write will fail but that might have been only my setup.

Quas7 commented 3 years ago

To get back to the orignal topic and close this. I tested now several hours with 0x00 instead of 80 (0d80) to get ~270kHz of display com speed and away from the assumed 187kHz(?) motor PWM harmonics.

I do not see any more display glitches and I do not notice any other issues with this.

0d80 = 0b 0101 0000 = ~320 kHz clock and divider 1 0x80 = 0b 1000 0000 = ~380 kHz clock and divider 1 (this would be the default setting) 0x00 = 0b 0000 0000 = ~270 kHz clock and divider 1

I will therefore start a PR for others to test this as well.

image

AbeFM commented 3 years ago

@nhabes79 There is one more thing to try as I ran into this for an MKS servo42b recently. In settings decrease the communication speed to 240kHz and set it to "Software System Reset" image

Oh, Ah! I didn't know this end could negotiate for slower speeds - totally I'll do that, the 4MHz would rarely, rarely work.

All flags shood look like in this screenshot (readout from a S42B): image

Especially the WDG_SW has to be enabled, otherwise it will reboot continously.

And there's a good chance this is at the heart of my rebooting continuously issue. My flags were all messed up, I'll take another look.

Pretty cool about the screen timing. Hasn't been an issue here, but it's a good approach.

swanepoeljan commented 3 years ago

@Quas7 Regarding the PWM frequency, I hooked up my scope to the VRef pins of each driver and tested it. It was indeed very close to 187kHz so I can confirm it. Wasn't spot on but could be because the MCU uses the internal clock...

caesar1111 commented 3 years ago

got the programmer as mentioned above.

changed the OLED freq to 0x00 = 0b 0000 0000 = ~270 kHz clock and divider 1 in oled.c

changed the main.c to int16_t kp=30; // caesar: changed from 30 to 30 (no change so far) int16_t ki=5; // caesar: changed from 10 to 5 int16_t kd=200; // caesar: changed from 250 to 200

installed STM32 ST-LINK Utility v4.5.0.exe

updated the programmer: image with the current firmware: image changed the target setting: Connections setting freq ot 240kHz and Reset Mode to System Software Reset image

disconnected the S42B board from the stepper and connected the programmer: S42B pin -> Programmer PIN: SWCK -> SWCLK SWDO -> SWDIO GND -> GND 3.3V -> 3.3V (yes, 3.3 was working for me without any issue)

Erased the chip

And just hit program to upload the S42BV1.0.pioenvs\BIGTREE_S42B_V1_0\firmware.bin which I compiled with visual studio code......

.....I went without any problem. Now I connected my spare newly programmed S42B incl. stepper to the printer and running a static test of the display stability. if that works out for some hrs I will install the stepper and start to do a dynamic test.

So thanks to all for helping me to get so far. I will post if all the test run successful and read up on the best PID setting....

caesar1111 commented 3 years ago

...ok, the OLED shut down on its own after about 8hrs.... but way better than the 30 sec. before flashing. I was retrying with the 0d80 = 0b 0101 0000 = ~320 kHz clock and divider 1 setting.... but while compiling the following error is showing: close_loop\src\Hardware\oled.c:224:15: error: invalid suffix "d80" on integer constant OLED_WR_Byte(0d80,OLED_CMD); so should the value rather be 0x50 to math the binary 0101 0000 which, translated to hex is 50? ...or am I completly wrong?

swanepoeljan commented 3 years ago

You probably figured it out by now, but you could use just "80" or "0x50" (which is 80 in decimal), so it should read: OLED_WR_Byte(80,OLED_CMD);

Quas7 commented 3 years ago

@caesar1111 I would opt for testing 0b 1010 0000 = ~410 kHz clock and divider 1 next. The 0d80 is the default in this repo, if I remember correctly and did not solve it for me.

It could also be, that it is just too fast. So using the divider to get down to 100kHz might be next and should not be an issue as there are no animations running on the display. This would be maybe: 0x02 = 0b 0000 0002 = ~270kHz / 3 = ~90kHz

caesar1111 commented 3 years ago

No success! I was testing the complete frequency spectrum up and down. (0x02 up to 0xF0) and especially with the divider 2 I was doing literally every step possible. And since I have two steppers installed, I did it at two…. No success! Either the display is getting black, the flickering is improving, the lines are shifting of the letters are double size. Whenever I do a static test, everything is fine for some hrs, but as soon as I am printing, the errors occur again. But here is another fact which was not discussed before. In total I have 3 preassembled closed loop board and steppers sets. One running without any issue. The two others currently installed with both issues, but different ones while flashed with the same firmware. So I started think if this is not only related to the closed loop board only, but also to the attached stepper motors???? @ the others experiencing the problem: Are you running a preassembled set or are have you assembled the closed loop board to a stepper of your own? @Quas7: I was even testing your precompiled firmware for the lazy ones. One display went black after 5 min printing, the other one was flickering for 1h and then went black as well…. Now I bought 2 more S42B sets directly from http://www.biqu.equipment/ (not via Aliexpress) and hope for better quality this time. I will keep you posted.

Quas7 commented 3 years ago

Very interessting and thanks for the testing and feedback!

Could you do one more thing and change the OLED displays around once?

I am quite sure they buy those from various sources and the line termination on them might vary etc. Just to make sure, we do not optimize on the wrong end. ;)

caesar1111 commented 3 years ago

Hi, that was one of the first things I tested with the original firmware. Now I also did it with your "lazy" version. Even the display coming from the one S42B set which is showing no errors is failing on the other sets. So it is either the closed loop board only or the combination of the board with the preassembled stepper motor. I am curious about feedback of the others facing the issue. If they all were using the sets of if this issues also occurs with board assembled to a different stepper (which would mean, it’s a board only problem).

Quas7 commented 3 years ago

I had always the suspicion that it depends on the motor size and its inductance and on the set max motor current. Slow moves did not kill the OLED but rapids have been very efficient to kill it.

EDIT: I ordered everything to build a small diy H-field probe. I always wanted to do this and I will test this on the board as my first trial on the next weekend, I think.

nhabes79 commented 3 years ago

Been busy this past week and haven’t had time to look at all the new stuff to read! You all are a wealth of knowledge. I’ll try all the suggestions you mentioned tonight, Quas7.

AbeFM, I’ve settled on these values for my CoreXY and my Cartesian.

P 60 I 0 D100

This has worked well for me. Have to be careful with P value, especially with larger prints. I made a test rectangle to fill up 2/3 of my print bed. If you go too low on the P value, it will do an odd looking overshoot. It does the same kind of curved line overshoot as if a CoreXY printer has the wrong belt tension and isn’t perfectly squared.

I is still 1 or 0 for me. Seems to work the best

I messed with D the most. I was looking for the best possible value to remove as much “hum” from these motors. Doesn’t seem to be any perfect values that I can find. The best I could do is take care of any rattles on my printers that the humming from the motors would magnify.

As for print quality, it’s there. It’s just as good as the 2209s with exception to a little bit of salmon skin. However, I have no ghosting problems at all with the S42B. That surprised me as I typically did have some ghosting issues with the 2209s.

Quas7 commented 3 years ago

I really wonder, if the salmonskin would get less pronounced with a 10bit sine lookup table compared with the 9bit implemented for the stm32 here. Was also a performance discussion at the MKS Servo42b github. The misfittech original uses 12bit (or ever 14?) but has a faster uC as well.

Quas7 commented 3 years ago

I ran some quick tests with a quickly build H-field probe and a 4€ 30dB RF-amp to see the emission spectrum of the S42B. I am limited to 100kHz (lower limit of current RF-amp) and 63MHz (FFT limit of my Redpitaya Scope). All these results are relative measurments so do NOT consider the dBm as "calibrated" at all. ;) And, before anybody else points it out - yes, I will have to redo this with a battery powered pre-amp. ;P

20201016_223409 (1)

Background noise free air 100kHz to 10 MHz image

100 KHz to 1 MHz image we see the switching power supply for the RF-amp that couples via DC. I should use a 9V battery here before proceding!

100 kHz to 400 kHz image And a bit better the RF-amp power supply again. ;)

STM32 under probe, 100kHz to 63 MHz image At least the main clock is where it should be around 48MHz. So this setup actually seems to work (not calling it anything validated but... okish for a DIY project).

STM32 under probe, 100kHz to 10MHz image I will have to check against a STM32 F1 with bare minimum code to see, if all these peaks are actually code related. Could these peaks be timer emissions !?

As the noise floor from my supply is too heavy, I will improve this later this weekend, i.e. go buying a stupid 9V battery. But, I see 140kHz and 170kHz peaks already for the stepper drivers. And also very broad peak for the on-board buck converter of the S42B - that might also a possible source for the display issues.

For anybody interessted in dublicating: The setup should be limited by the RF-amp with 100kHz to 2GHz. It is possible to modify the RF-amp with bigger coupling capacitors to RF-in and RF-out (100nF -> 1uF?) to get ~10kHz to maybe 800MHz to make it more usefull for this type of tests. Did not yet check with my NanoVNA what the preamp can actually do as I need some attenuators first to not fry my Nano. ;)

swanepoeljan commented 3 years ago

Great work! Would be interesting to see what signals pop up!

Nice H field probe! Is the inner soldered to the outer where the loop closes? How does the RBW work when using the Redpitaya, can you select it or does it automatically adjust depending on the span?

Quas7 commented 3 years ago

Thanks. I also found a 9V block in a drawer. So, tonight I will start checking in detail.

I build this H-probe with slit/break in ring center and conductor+shield soldered to shield to close the ring. image I think, with some 3d printed fixture I could get this a bit smaller. The board is just a bit to crowded with connectors to get the probe perfectly placed.

Regarding the redpitaya the standard FFT app should be auto-adjusting the RBW to the span according to the max datapoints it can hold. At least, I did not see a RBW adjustment option yet. But, I did not investigate deeply yet although the informations should be somewhere here: https://redpitaya.readthedocs.io/en/latest/developerGuide/125-14/fastIO.html

There are also other FFT options as market apps available but I did try them yet as these are not compatible to my beta-FPGA image currently running on the pitaya (thats only a matter of 3min download and SD card flashing).

Quas7 commented 3 years ago

And here the results for 100kHz to 1000kHz with clean 9V battery supply.

free-air Background measurement (on battery quite clean but some faint bursts in low kHz from somewhere, e.g. a fan maybe) image

strongest peak around 460kHz and harmonic at 920kHz over the buck converter coil and diode. image these peaks spread out all over the board... therefore upper limit 450kHz below to get details.

over Allegro stepper driver output stage 100kHz to 450kHz image Waterfall diagram: lower half motor disabled, upper half enabled Peaks are around 143, 153, 230(quite broad) and 296kHz

probe with a loop of a single motor wire (A1?) without load 100kHz to 450kHz image Waterfall diagram: lower half disalbed motor, upper half enabled

as above but motor "humming" heavily because of bad calibration image

as above but motor steady on position image

and now the crazy part... Probe over OLED board seperated with 20cm DuPont wires from the S42B image Here I will retest with changed frequencies (0x80, 0d80, 0x00, etc.) And if you compare with above Allegro driver there are even stronger double peaks at the same frequencies around 150kHz

and probe over the DuPont wires image These lines are quite busy! Does not supprise me much, that this communication is quite sensitive to RFI. Maybe an I2C or SPI display would perform better in this environment? Edit: a little correction. These FFT peaks are likely a result of one stronger square wave like a clock signal. My OLED runs on 0x00 (270kHz) but this is something far below that.

I would concentrate my testing for the OLED stability now on 240kHz to 280kHz and around 340kHz. But for testing, the motor requires some load to get full current to emit the full RFI.

caesar1111 commented 3 years ago

Its official, BTT has an issue with the quality, at least with the preassembled sets! I now got my two sets directly bought at the BIQU BTT online shop. Packing was intact but plugging in and testing with OLEDs show a drastic result. At one set the display stays only on for about 5 sec. at the other you at least have to move the stepper, but than the display is going black immediately. (And yes, OLED is working since I have at least one out of 5 S42B sets which is ok, so I was able to test all the OLEDs with this one and all OLEDs are fine) I am still waiting for some feedback of someone who was assembling a closed loop board to a stepper of his own and I he was facing the same issues…… I contacted BIQU with a request for help. We will see….. @Quas7 : did you have a chance to find the perfect frequency?

Quas7 commented 3 years ago

@caesar1111 so far, I had no more issues with 0x00 but I did not test under heavy load yet. I do not think this is production quality but more likely a design issue.

As you have the biggest sample pile currently, you could try one more thing on the worst sample. Try to attach the OLED with DuPont extension wires or similar to the board like this: 20201017_232735.jpg Or just pull the OLED a bit out of the connector so it has 2mm more distance to the mainboard.

The OLED sits right above the inductance of the buck converter and that one is emitting 460kHz right to the point where the main IC of the OLED sits... maybe it is just a matter of distance between those two components to make it work.

If this does not help, one could add a ferrite bead or choke or even a toroid to the DuPont extension wires: image image https://www.analog.com/en/analog-dialogue/articles/ferrite-beads-demystified.html These ferrites can normally be retrieved from old bigger switching power supplies (PC ATX or laptop "bricks").

Quas7 commented 3 years ago

Just to confirm: I baught 3 pcs of non-kits (only boards) and experienced similar issues with OLED (freezing, black, corrupted fonts, etc.)

2 of them run on NEMA 17 pancake motors as extruders without issues with 0x00. 1 test setup on a 47mm NEMA for debugging - also no issue so far with 0x00.

Quas7 commented 3 years ago

Maybe I should have done this step before jumping to RFI measurements. ;)

Build a strip-board debugging port for the OLED terminals (next time, move the next upwards connectro away from the 2nd pin row...): image

I only show a few pins... they all behave very similiar.

CS Pin motor enabled standby image 50us/div image

CS Pin motor under load image 50us/div image

D0 Pin motor enabled standby 1us/div image

3V3 pin motor enabled standby 20us/div image Motor under load image

Looking at the singals here I did not yet see the event that could kill this link - all fine from my perspective and nothing boarderline. Maybe the 3.3V supply is a bit noisy under load but I do not expect that either to kill the communication.

I will try now different frequencies for the OLED to get an instable setup to debug.

swanepoeljan commented 3 years ago

@caesar1111 I assume this was with the stock firmware they came with? Just curious if these new ones behaved the same with the fix (0x00) proposed by Till...

caesar1111 commented 3 years ago

...just flashed the 0x00 firmware and used 10cm wires to put some distance between the board and the OLED... ....one OLED is now running fine, the other one is showing artifacts but is no longer blacking out. So its getting better somehow. I will get some ferrite bead and longer wires.... I will also play with the new arrival with the worst performance and put it on another stepper, just to see if it is still so bad....

caesar1111 commented 3 years ago

So here we are after a 8h print.... at one stepper I have no longer issues. at the other, I got a lineshift after 15 minutes printing 0 after the 8hrs print, display was back to artefacts, but did not turn off itself. 1 I am now experimenting with different frequencies until I the get ferrite beads delivered. I will aslo try out a 50cm patchcable, so I can place the OLEDs on the frame of my printer... And talking about stock firmware... with the 20cm patch cable extension, even the stepper with the worst stability (OLED was switching off after 5 secs.) now the display stays on, when the stepper is moved. I am planning to put all my 5 S42Bs on the printer X,Y, double Z and Extruder...... then I can test all the steppers simultaneously

caesar1111 commented 3 years ago

....20cm more patchcable, an old magentic stickytape and frequency at 0xA1 did the trick.......so far. Now the OLED is on for 5hrs printing without issues: 3 (The last line missing is just on the picture due to the low frequency.) I will now do some durability testing...... ....ah and the BTT serverice contacted me via Messanger. Lets see what the are suggesting..... . . ....good news from the testing..... still no failure with the setup, so the problem seems to be solved. I will try to experiment with insulation of the OLED when plugged in, but not expecting to much. . . ...bad news from the BTT support. they are playing the waiting game. I will continue to push for some answers.

Quas7 commented 3 years ago

ok, than one permanent solution might be to add a few ferrites or chokes to the display lanes on the PCB for next generation S42B.

Quas7 commented 3 years ago

I experimented a bit with the OLED frequencies to check, if I can make an unstable setup with wire extensions in place. And it looks like I have been "on the wood way" (German saying for on the wrong track).

F_OSC does not have any impact on the communication speed over the lines and is only changing the refreshrate of the display. Quick verification with a smart phone camera shows this quite nicely for 0x00 vs 0xF0.

On the other hand, checking the D0 (clk) line shows 1.4MHz clock bursts (700ns) and also some higher glitches with uneven spacing (400ns in between) and not 50:50 duty cycle on the clock (more like 40:60 on:off) image

The function doing this is just OLED_WR_BYTE in oled.c starting in line 39. It is bit-banging the signals on the pins. So I added a few nop's to the code to make it a bit slower with 1000ns or 1Mhz.

void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{   
    uint8_t i;  
    if(cmd)    
        OLED_RS_H; 
    else 
        OLED_RS_L;
    OLED_CS_L;        
    for(i=0;i<8;i++)
    {             
        OLED_SCLK_L;
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ) ;//added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        if(dat&0x80)OLED_SDIN_H;
        else OLED_SDIN_L;
        OLED_SCLK_H;
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        asm volatile ( "nop":: ); //added by Quas7
        dat<<=1;   
    }                
    OLED_CS_H;        
    OLED_RS_H;        
} 

The result is still the same stable display for me but now hopefully a more robust communication. image (I am not sure, why there are shorter periods in the clock output, e.g. right next of the markers in the figure above...)

This should mainly help to seperate the data signal via SDIN_H / _L from the rising/falling edge of the clock. And this might also explain, why adding inductance/wire helps a bit with this issue as this should increase the rise and fall times slightly.

EDIT: maybe we should also add a few nop's before sending the data in the for-loop to get CS and RS edges a bit seperated.

@caesar1111 if you still have problems with one of your displays, would you please test this? :)

Quas7 commented 3 years ago

after 10h enabled on my desk without movment I get a very similar line shift as caesar 20201024_121708.jpg

Will now increase timings more and check.

Quas7 commented 3 years ago

I digged into the digital communication now a bit depper and hopefully I can issue a PR next weekend.

The display runs on an SPI 4-wire interface according p.18 of the SSD1306 datasheet (previously posted already). A little background for SPI debugging can be found here: https://hackaday.com/2016/07/01/what-could-go-wrong-spi/

The data (SDIN or D1) is sampled by the OLED for every rising edge of SCLK (D0). CS and D/C need to be set before SCLK (D0) rises for the first time and SDIN (D1) should be set also before SCLK rises. image

I hooked up an open bench logic sniffer to check for any timing issues. image

What bothers me a little bit is the clock jumpyness from 1.429MHz to 2MHz (500ns). These jumps always happen when SDIN goes high during clock-low (e.g. 113us here). image

It looks like this piece of code is not balanced for clock cycles. The "true" path executes naturally faster than the "false" else-path.

oled.c

        if(dat&0x80)OLED_SDIN_H;   //check, if dat==1 and set SDIN high if true
        else OLED_SDIN_L; //if dat==0 set SDIN low
        OLED_SCLK_H; //rising edge of SCLK

Unfortunatelly, I am quite an OLS-noob in setting simple triggers to catch SPI timing violations in order to get the actual glitch captured. But some violations I catched by brute force: image

So, I now just tried to balance the clock cycles for the if-clauses in the bit-banging routine and I will now check, if the OLED stays stable for a few days.

void OLED_WR_Byte(uint8_t dat,uint8_t cmd)  //adding some NOPs to reduce jumpyness of SCLK up to 2MHz and to increase timing margin between SPI signals
{   
    uint8_t i;  
    if(cmd) 
    {   
        OLED_RS_H; 
    }
    else 
        OLED_RS_L;

    OLED_CS_L;      

    for(i=0;i<8;i++)
    {             
        OLED_SCLK_L;
        if(dat&0x80)
        {
            OLED_SDIN_H;
            asm volatile ( "nop":: ); //compensate for faster timing for dat&0x80 being true
            asm volatile ( "nop":: );
            asm volatile ( "nop":: );  
            asm volatile ( "nop":: ); 
        }
        else OLED_SDIN_L;
        asm volatile ( "nop":: );  
        asm volatile ( "nop":: ); 

        OLED_SCLK_H;   // this rising edge of SCLK triggers the sampling by the OLED SSD1306
            dat<<=1;   //shift dat one bit
    }                

    OLED_CS_H;        
    OLED_RS_H; 
} 

at least on logic level it looks less jumpy this way: image

Edit1: Failed after 30min... I will now use 0x00 instead of 0x80 in parallel as the error looks different than before.

Edit2: Still same issue... will decrease the MHz now again. 20201024_232824.jpg

Edit3: a bit suprisingly, running the OLED F_OSC as fast as possible with 0xF0 seems more promising than 0x00 or 0x80. Looks like there are two failure modes involved? The buck converter 460kHz and the SPI timing?