I have a loop of code running on a Mega 2560 that is running at a certain speed, which I get from an Arduino Uno. I have tried to talk with I2C but when I receive the data from I2C, the whole code stops and then resumes when the communication ends. Does this also happen with SPI or can I be transmitting and receiving with SPI inside my main loop?

This is my code. I have to make my own PWM, because the analogWrite function isn't precise enough. When I send data to the Arduino, and since this is in the main loop, the motors stop. I have 4 of these blocks running.

digitalWrite(backLeft, HIGH); //Back left motor driver code
digitalWrite(backLeft, LOW);
  • 1
    Please post your code so we see exactly what you have done and possibly investigate on what could be wrong.
    – jfpoilpret
    Dec 4 '16 at 23:17
  • It is hard to believe that the Arduino's PWM can not give you the precision you desire. But if it does not, I would first read the ATmega640 chip specification regarding its PWM hardware. It is very possible that if you rewrote the Arduino PWM driver you could improve upon its precision. Regardless, the way you are creating the PWM signal, even the slightest disturbance (any interrupt) will case a problem.
    – st2000
    Dec 5 '16 at 4:12
  • I think it's nonsense that analogWrite (or native PWM) can't provide the accuracy needed. It seems like you're using it to drive motors. if you see a difference between analogWrite(50); and analogWrite(51); , then it may be inaccurate. But it isn't.
    – Paul
    Dec 5 '16 at 7:07
  • 1
    This is the worst way of generating a PWM signal: you cannot do anything else without disrupting the signal timings. It would be better to use interrupts, like the Servo library does. Best would be to generate the signal by a hardware timer. If 8 bits is not enough, use one of the 16-bit timers (you have 4 of them). Start by reading Nick Gammon's tutorial on timers, the configure Timer 1, 3, 4 or 5 to your taste. Dec 5 '16 at 8:52

Some (complex) processors have dedicated hardware to handle the I2C or SPI transaction. Other (simpler) processors do not. In such processors with no supporting hardware the bus must be emulated using software. This takes time away from other processor activities.

You will have to determine if the processor in your Arduino (and there are many different types of Arduinos which use many different processors) has hardware to support I2C and / or SPI bus transactions with out help from the software.

Note: Even in cases where there is hardware to handle I2C and / or SPI transactions, badly written software can still trip up the processor and make it unavailable for other purposes.

Note: Even in cases where there is no hardware to handle the I2C and / or SPI transactions, well written software can handle a moderate demand from tasks while also handling serial bus processing.

[Comments based on Arduino board type added later to answer:]

You are using an Arduino Mega 2560 which uses the Atmel ATmega2560 processor (one of several described in the linked-to specification). Searching the ATmega640 documentation shows matches for "TWI" (Atmel's equivelent to Philips' I2C) and SPI. So, if the I2C or SPI driver software has been well written for the ATmega2560 processor, it should be using the processor's hardware. Which makes the I2C or SPI feature more (but not entirely) immune to what ever else you have the processor running.

At this point it would be prudent for you to check if you are using such a driver. Make sure you are not using a driver which "emulates" these protocols in software. Also, make sure, if there is a hardware restriction, that you are using the pins on the processor designated for the type of bus used. Some driver may be extremely flexible allowing you to designate a pin with out hardware support and automatically implementing the protocol in software.

[Comments based on code added later to answer:]

You are your self implementing what might be handed off to built in processor hardware in software. Specifically you are emulating the PWM hardware feature in software. It is likely that even the most efficient I2C or SPI code (even with supporting hardware) will effect such sensitive software.

It would take a fair amount of work to make this software "work better". In general, you should consider not using delays and implementing a call-back paradigm based on a timed interrupts.

Alternatively, you might investigate why the Arduino PWM driver does not give you enough resolution. The hardware may in fact provide more resolution than the driver permits. Re-writing the PWM driver may be easier solution.

  • This answer may not be of practical use to you. But you have not given many details regarding your situation. If you edit your question to be more specific - I'll attempt to edit my answer to be more practical.
    – st2000
    Dec 5 '16 at 0:37
  • I updated my question and added code Dec 5 '16 at 2:23
  • 1
    1) The Arduino Mega 2560 uses the ATmega2560 microcontroller, not the ATmega640. 2) Both the ATmega640 and the ATmega2560 have a dedicated I2C interface, but Atmel calls it “TWI” (2-wire Serial Interface). This interface is supported by the Arduino Wire library. Dec 5 '16 at 8:45
  • @EdgarBonet, thanks, I missed that. Oh, I see what I did. The Atmel data sheet is for many chips ("ATmega640/V-1280/V\-1281/V-2560/V-2561/V"). I just picked the 1st chip in the list. I will change my answer.
    – st2000
    Dec 5 '16 at 13:29
  • The built in pwm function changes the duty cycle based on a number of 0-255, 127 would be a 50% duty cycle of 1 milliseconds on then off. That's great but I also need a duty cycle off 2 milliseconds on and off which would be 255 which is 100% duty cycle and the motor doesn't spin at all based on arduino.cc/en/Tutorial/PWM. I know the mega has a 1000Hz pwm timer also but the analog 127 is the same for both timers Dec 5 '16 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.