I2C Sensors in Smoothieware

Hello everybody,

Bottom Line Up Front:
I wrote a module that reads temperature over I2C from an IR temperature sensor every second while my printer is printing. When I start a print, the Smoothie does read a temperature every second, however the print speed becomes erratic (randomly increases and decreases), and after a while (order of a few seconds to a few minutes) the Smoothie will crash (specifically, movement stops and serial is disconnected, have to unplug the Smoothieboard).

I think the issue is with the I2C, but I wanted to bring the issue here to get some opinions. Is I2C too slow for Smoothie to monitor it and generate the steps for the motors? Or maybe it is the way I’ve implemented it? If I2C is the wrong solution, would SPI work? Since my sensors use I2C, an SPI solution that I’m thinking of would have an intermediate controller to convert I2C to SPI (much like the Universal Panel Adapter).

If you need to see the code to help, let me know and I can do so.

A few details:
Prusa i3 Motion (cartesian)
Smoothieboard 5x
Sparkfun MLX90614 IR Temperature Sensor

Background:
I am a university researcher developing a 3D Metal Printer (smoothie powered, at that) that uses arc-welding technology instead of the more expensive alternative technologies (such as Direct Metal Laser Sintering, etc.). In case you are interested, our results so far are very promising. We have a need to measure the temperature before and after the weld puddle passes over the base metal, in order to get a sense of the properties of the part, and to eventually lead to a feedback loop where the Smoothieboard will be able to adjust print speed and wire feed rate based on temperature inputs.

Imported from wikidot

From your symptoms, I’d say this has nothing to do with i2c, but has to do with the way/where you actually send the serial printf from. You have to be very careful with that in order not to disturb smoothie’s normal functionning. Take a look at other modules and how they pass information. It has to be in the main loop, it can’t be in an interrupt or wherever else you are reading the data.
Is your code somewhere or github ?

About metal 3D printing, I might have some smoothie-related projects that might be of interrest to you, please email wolf.arthur@gmail.com

Cheers.

Thanks for the quick reply.

I do have a GitHub for the code. I can’t post links but its at /buchananmatt/Smoothieware, the Forgeware branch.

The module specifically is at buchananmatt/Smoothieware/tree/Forgeware/src/modules/tools/forge.

  • Forge.cpp and Forge.h are the main files, this is where printing occurs.
  • Bus.cpp and Bus.h are for reading from the sensors and controlling the I2C bus.
  • mlx90614.cpp and mlx90614.h are the library files for the MLX90614 IR sensors I’m using.

Currently everything occurs during the on_second_tick event, and printing is the last part of that event. I think it’s similar to how the TemperatureControl module works.

Thanks!

yep you can’t do a printf inside on_second_tick, that’s in an interrupt it’ll never ever work reliably

you need to store your string in a variable, then in the on_main_loop event, if that string isn’t empty, you printf it, very simple

oh and if you do i2c coms, you want that to happen in the main loop, not in an interrupt, in the same way

no printf or communications in interrupts, is the message

Okay so I think it might look something like this:

on_main_loop()
get_direction()
get_temperature()
print_profile()

How would I go about with the timing? I guess what I don’t know is when and how frequently on_main_loop is called.
I’m hoping to perform these actions once or twice a second.

it’s supposed to be called many times per second. if you find it’s not enough, you can do your stuff *also* in on_idle

So I’ve been trying to figure out what’s going on, but haven’t had any luck yet.

When I use on_main_loop, the smoothieboard hangs up immediately after I start a print, with nothing printed to the serial monitor. I’ve tried debugging by removing some functionality from my module (get_direction, then get_temperature, then print_profile, then a combination of the three), but the results are either the same or Smoothie will fail to boot entirely.

Maybe I’m not using on_main_loop correctly (although it doesn’t seem complicated)? I really don’t know, so I wanted to bring it up. Thanks!

Got it working.

The problem was a combination of things: one is I use the on_second_tick() event to set a flag variable, then on_main_loop() and on_idle() will check to see if that flag variable is set, if so then execute code. Second is in my get_direction function, it would make a new block pointer that points to the currently executing block, find the direction, then delete the pointer every time it ran. I changed this so only one pointer is made and is never deleted, and it works!

Thanks for the help.