I have an Arduino Duemilanove (with ATMega328P), and I also have an I2C device to interface with, the MD25 motor controller from Devantech.
This interface was running fine until a couple of days ago when I belive I burnt out the data line (SDA) on my arduino 328 chip (dont know how). The clock line was still pumping out a solid 100Khz clock, verified with my oscilliscope. but nothing on the dataline, so I assumed the ATMega328 is not very well.
I ordered a new ATMega 328P-PU from the same supplier as the board with the bootloader preloaded as I do not have an ICSP programmer. Putting the exact same Arduino Sketch that was working perfectly with my old 328 give me an exact 200Khz clock on SCL!! Needless to say the I2C interface does not work.
The only other thread I could find about this was one regarding Serial data being sent twice as fast. (Which i tried to link but I need more messages).
My board has a 16MHz crystal, and it worked perfectly with my old chip, I thought that maybe my chip is an 8Mhz and this is getting its speed doubled? I ruled this out when I tried timing some pin HIGH/LOWs with delays of 500ms, it clocks correctly at 500ms on my oscilliscope.
I am left with the problem being timing and I2C related, the chips are exactly the same apart from a four digit number (0910 and 0927) are these the batch numbers?
I have been stuck with this for a couple of days so would really appreciate any ideas you guys could think of?
SCL Frequency = CPU Frequency / ( (16 + (2*TWBR)) * TWSR)
So... currently my TWSR is 0xF8, which is 11111000, or, a prescaler value of 1.
My TWBR is giving me 0, and my chip SHOULD be 16mhz (at least the crystal is) so...
I have tried writing 72 to the TWBR but no joy, can you suggest how I can get this value to stick/take effect?
Edit: My first chip giving me 100Khz is right... but reading the TWBR of that is giving me 0. Which makes me think writing TWBR will do nothing. I cant seem to find the code for the TWI library? Would there be anything in their to help?
Bit of a wild goose chase that TWBR. I was stupidly checking it/writing it before i called Wire.begin();
Here is the call from twi_init which is called by Wire.begin() to set TWBR.
TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;
Checking TWBR after this occurs gives me the magic 72! Only this happens on both chips, the new one is still giving me the wrong clock of 200Khz. Argh :-?
Okay... Ignoring the fact that this is totally wrong, setting 152 as the TWBR value would give me a value of 50Khz. Infact after checking with a scope it gives me my desired frequency of 100Khz, so something is definatly wrong with I2C here.
I decided to push on as I'd got a 100Khz clock and try and push some data though.. i think my data is very off. I dont know how long a pulse takes on the dataline, but most of them on my scope are 20us, I would assume they should be very close to 10us for the clock to work? (The clock being 10us??)
Anyone know better than I why i have to increase my TWBR to get 100Khz?
Thank you, my prescaler is set to 1. Or (TWSR = 11111000).
Having set TWBR to 152 I now get a 100Khz pulse on the Clock Line.
My data appears to be correct, checking on my oscilliscope I see the data bits I expect (7 bit address, write bit, ACK bit).
The ACK bit is getting pulled down for my EEPROM but not for my motor controller... which makes me think I bust the motor controller at the same time as my original chip =(
Thanks for the help though. I will ring my supplier in the morning to see if they have any ideas. I really cant make head nor tale of the clock problem cause the data appears to be right!!
I am using very short wires to test this, I was using 1k resistors with it working fine, I switched to 4.7k resistors as you suggested with no effect. All my logic is running at 5v and all grounds have been checked.
I know (think) the first chips SDA is broken because it reads 0v at all time when it should be 5v whilst no data is being carried on it. (And you see no data whilst some is being sent in code).
Checking the SDA line of the second chip with the hacked TWRB to 152 shows clean data, the address the read/write flag, except the ACK is not pull down as it should be by the motor controller. Needless to say no data is returned.
All this worked a couple of days ago until nothing would work, I must have burned out my 328, which is why I bought the second 328 (which clocked at 200Khz), I can only assume I have done the same to the controller?
Not understanding why things go wrong in the first place - sure is frustrating as you may have yet another faulty CPU or more (sorry to even suggest this).
One thing I noticed from the MD25 spec. is that it is designed to be powered from a battery (e.g. 12V led acid). Without a battery in the circuit, there is potential risk with inductive loads (e.g. motors) sourcing back power spikes onto your power rails when breaking. You may want to consider this if it is applicable for your test environment.
Thank you, i'm not sure if the induction was an issue in the burning out of my lines. I am using a 12v power transformer in place of a battery whilst testing. I will in future use a diode from this to my motor controller. I am powering the arduino off the USB power, and the motor controller (with no motors at the moment) off the transformer, with joined grounds, this should help seperate the inductive load from the Arduino?
I am currently waiting on a reply from my chip supplier, I will either get them to replace the chip or fix the issue. If i get a chip which comes brand new and gives me my 100Khz clock and the MD25 is still not responding I can only assume I have blown that also.
As long as a motor is not connected, inductive loads would not materialize and explain the issues with burmed out chips.
When you operate a motor (power the rotor windings) this will transform into torque and movement, but when you remove power the opposite is true. The motor inertia will keep the rotor turning for a short while and induct electricty (high current) that may appear on your power rails (depends on the motor controller design). When a battery is the power source, this is not so much an issue as it will act as a gigantic capacitor absorbing the reverse power (it may even be desired as the battery could recharge from this current). When powered by a switch mode power supply with shared logic ground however, the reverse power may cause harm to logic connected to the controller and also the controller itself.
The issue with inductive reverse loads is not something a motor controller designer would forget or ignore as it is fundamental to deal with this properly. If a controller is designed specifically for battery power however it may not work well with switch mode power supplies. Yoy may want to seek advice from the motor controller supplier/manufacturer if you plan to operate the final design from a switch mode supply rather than a battery. Asking the supplier is good as that they can be made accountable for their advice.
I hope you find the cause of your issues and share your gained wisdom with the forum.
Sorry for the super late reply, I found out that my MD25 was broken so I sent it back and got a replacement.
I used the MD23 code that someone had posted online, you probably have the same code.
I think I did have to change this code to get the encoders to read right.
long MD23::getEncoder1()
{
// read a 32bit long value containing the encoder reading.
// the reading of the highest byte capture the value.
long first = readRegisterByte(ENC_1_A_REGISTER);
return (first << 24) ^
(((long)readRegisterByte(ENC_1_A_REGISTER+1)) << 16) ^
(((long)readRegisterByte(ENC_1_A_REGISTER+2)) << 8) ^
(((long)readRegisterByte(ENC_1_A_REGISTER+3)) );
}
long MD23::getEncoder2()
{
// read a 32bit long value containing the encoder reading.
// the reading of the highest byte capture the value.
long first = readRegisterByte(ENC_2_A_REGISTER);
return (first << 24) ^
(((long)readRegisterByte(ENC_2_A_REGISTER+1)) << 16) ^
(((long)readRegisterByte(ENC_2_A_REGISTER+2)) << 8) ^
(((long)readRegisterByte(ENC_2_A_REGISTER+3)) );
}
Now however I've got the same problem, so I think my MD25 is broken again... Its not a very reliable board!! I'm looking for another board to drive the motors, as they seem reliable. Basically all you need is a H-Bridge and some way of reading the encoders. Basically quadrature with A+B pulses.. I'm still looking into this...
Can anyone recommend a good motor/driver combo that doesnt break so easily?? But has encoders built in.