OctoPi not reading SD card or print progress from Ender 3 (SOLVED)

Hi All,

I can confirm that it works in an Ender 3 Pro purchased at the end of August.

Thanks for your contributions

I used Ender-3s printer, I cant get sd card file from octoprint. I just follwoed b-morgan steps , but I still cant get anything . So I Unmark "Enable automatic firmware detection" and mark "Always assume SD card is present- Repetier" in Octroprint Settings / Firmware & Protocol.It works well.

1 Like

plug-in works like a charm! thank you!

I guess what the plugin does is to intercept every line received by the printer. If it contains "SD" then it replaces "SD" with "TF". This approach has the drawback that a function is invoked (the callback itself) which itself does further more calls (basically find&replace).

Here I provide an alternate solution by directly patching the file that handles Octoprint's communication with the printer (comm.py) which from my point of view is more performant then to hook in a plugin. I have octoprint installed via pip in my home folder. Alternatively you can change COMM_FILE to whatever location fits for your installation.

LINE_WITH_SD_IN_IT="elif 'SD card ok' in line and not self._sdAvailable"

if [ "$LINE_IN_COMM_FILE" != "" ]
  echo "It seems the file $COMM_FILE requires patching. To continue hit enter"
  echo "Please restart octoprint"
  echo "No need to patch $COMM_FILE"

I placed this file in my home directory and made it executable (chmod +x). It has to be executed every time an update of octoprint overwrites the comm.py file.

I had the same issue and read the whole thread. It's disappointing that no one found the correct answer in this thread.

No plugin or changes to files are needed .. @NRom posted the correct solution twice:

1 Like

@Scott_Westberg b-morgan's #6 post may have been helpful previously but is no longer the best method, @NRom has posts below on how to fix this through the GUI, can you please change the solution to his post?

Why? If the solution he choosed works for him. The solution of NRom is another solution.

All I read here are workarounds, no solutions. I also tried the "Always assume SD card is present- Repetier" which resulted in other errors - I was no longer able to connect to my printer.

The problem is located in the Ender3's firmware. A solution would be to patch that - but that's out of scope. Another cleaner solution would be not to catch fixed strings in comm.py. Instead use translations and provide a translation file for each printer so that the whole parsing becomes independent of the strings themselves.

That's not how communication protocols work.

1 Like

I am talking about implementation not the protocol.
By the way: where is this protocol being specified? I cannot find it.
Protocol means there is a contract how the data is communicated between peers. So if there is no such official specification, than you cannot rely that the messages received by the printers are all the same. So the parser should be more flexible - which could be done by sourcing according translations instead hardcoding fixed strings.

You really do not want to get me started on this discussion, especially not right now. Trust me.

Take a look here and here and watch this.

The only specification we have is a wiki everyone can edit, that's a nightmare for host software development, I'm already bending over backwards everywhere but at some point it just stops working catering to firmware forks doing whatever the fsck they want and a line has to be drawn to not make everything a completely unmaintainable mess for good.

Printer vendors and firmware devs have a responsibility too, yet for some reason I am/OctoPrint is supposed to shoulder all the work and maintenance overhead to keep things interoperable, and frankly, that's annoying AF. Your suggestion would make that even worse. And still it is actually the direction that the comm layer rewrite is taking, though not with a translation file, because just the communication strings aren't the only thing that constantly gets fscked around with by vendors who have no bloody idea what they are doing and breaking left and right.

... sorry. Rant over. Really a bloody sour topic for me that's causing me actual nightmares, literally.

Ah, now I see!
@foosel I am so sorry I did not intend to offend you. You did a great job with developing and sharing OctoPrint with us - so many people are greatful!
I am python & firmware dev too and I totally understand your frustration. I just stumbled upon this very special issue with my Ender 3, read the source in comm.py and asked myself how the parser could be extended so that the strings don't need to be hardcoded. I had no evil thoughts. Ich will kein Fass aufmachen.

Not hardcoded strings would mean that you don't have to reship the whole parser when some vendor f**ed up with a message. Instead just a single line in - what I call translation file - needs to be changed.
Following a very simplified example. I know this uses a dict but this can be tuned to anything userfriendly simple editable.

# tranlsation.py
Translation = collections.namedtuple('Translation', 'prusai3 ender3') # any other printer may go here
translations = dict(
    SD_CARD_INIT_OK_RESPONSE=Translation(r'^SD card ok$', r'^TF card ok$'),

def _(key, printer) -> str:
    return getattr(translations[key], printer)

# in comm.py
##~~ SD Card handling
    # assume the printer var holds the printer name, e.g. 'ender3'
    elif _('SD_CARD_INIT_OK_RESPONSE', printer) in line and not self._sdAvailable:
        self._sdAvailable = True

So if the Ender 3 again f**s up from "TF card ok" to "microSD card Okay" then one would only have to change the line in translations.py.

No worries. It's just really a bit of a stressful time for me right now (sponsor situation, RC, some Py3 compat stuff blowing up, on top of everything else). I'm sorry for blowing up.

I understand the idea behind your suggestion. The problem is it wouldn't avoid shipping, I really don't want to start reading stuff like that from a server on startup :wink:

Current approach for the new comm layer are (plugin extendable) protocol layers that hold the strings and other stuff that cannot be easily fit into a text file in so called "flavors" which then get selected either automatically based on detection or by the user. The idea would be in the future to then allow someone to write a plugin that adds a new "Ender 3" flavor to the mix, maybe also with detection based on M115 responses, and publish that.

You can take a look at the current implementation here: https://github.com/foosel/OctoPrint/tree/dev/commRefactoringNG/src/octoprint/comm/protocol/reprap/flavors


The problem is it wouldn't avoid shipping

That is totally correct! But: for people like me or other users in this thread it would be easier to "fix" such issues.

Current approach for the new comm layer are (plugin extendable) protocol layers that hold the strings and other stuff ...

Ah okay that sounds to me there is some heavy refactoring going on? To use plugins that hold everything that is required to handle communication with different flavors (printers?) is something I totally agree with.

You can take a look at the current implementation here

You really want me to do that? I am a very hard coder reviewer :smiley:

Yeah, that refactoring has been going on for a long time actually. I originally wanted to get it into 1.4.0, but that caused issues with the timeline due to the pending py2 EOL. It's still in the process of being worked on (though on hold while I take care of 1.4.0rc stuff - once again, which is another source of frustration). With that in mind, knock yourself out, if you want to look over it I'd be thankful, as long as you keep in mind that it's not final :wink: The whole octoprint.comm tree is actually new.