EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: SuzyC on August 01, 2014, 03:41:23 pm

Title: Help Me Continue My I2C
Post by: SuzyC on August 01, 2014, 03:41:23 pm
with Slave i2cRead below I start and successfully send an address from my Master PC 16F886 to my Slave PIC 16F886 and I see and acknowledge bit is clear, low clearly on my scope..works perfect, no problem.

But then the Master waits 5-seconds and sends more bytes as it should, I can see on my scope the correct bits are transmitted for all bytes, but the Slave refuses to set the 9th bit low to Ack any of the next  transmitted correctly bytes.

What am I doing wrong?  (PS: there are no other code/routines running in main/ISR to cause a problem)

 i2creset(); //simply resets Slave, Clocks out Clk or Data pin lockup if either is stuck low

Here is my initialization of the Slave :
   i2cinit();    //Setup of 16F886 as Slave. FOSC=20MHz (20mHz Xtal) i2C Baud = 400KHz, 7-bit addressing Slave/Master

//------------------------------------------------------------------------------------------------------------------------ 
 //This Slave 16F886 code sits in ISR This code works perfectly to detect Slave Address from Master and Acks.

   if(SSPIF) //set by Start or Stop i2C indicates Start Bit Detected
    // Idle is the startup and current conditioin, after reset, this is the TransmitReceiveState (TRSt=Idle) for my code
    // After Address is written to Slave by Master and Ack is ok, Master waits 5-seconds and then sends more bytes.

   if(TRSt==Idle) //Code starts running after turn on with this start up condition after MCU reset
    { RCEN=1;
   
      WaitMSSP();
      if( (SSPBUF & 0xFE)==Addr)
       {
        //Everything is perfect to this point, address is detected and Ack 9th bit is low and detected/sent to Master
       
            RCEN=1;
W4Byte0:
    WaitMSSP();     
    if(BF==1)
          { i=SSPBUF;
          }
         else goto W4Byte0;
          BF=0;          //Oh Oh! ninth bit shows *ACK =1  ...no ACK action!

         RCEN=1;

W4Byte:
       
WaitMSSP();
         if(BF==1)
          { i=SSPBUF;
          }
         else goto W4Byte;
         BF=0;
        }
    }
//--------------------------------------------------------------------

void WaitMSSP()
{
   while(!SSPIF); // while SSPIF=0 stay here else exit the loop

   SSPIF=0;       // operation completed clear the flag
}
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 01, 2014, 06:47:24 pm
Hi ... I'm trying to match your C to my PIC16F1847 I2C handler .asm...  Its been a while since i put it together......

#1..
 After a start interrupt  the buffer contains the device address , no need to check it just read the SSPBUF to a dummy . master will send next byte...  I think...

edit...
MSSP Data sheet 25.5.3.2

7-Bit Transmission
A master device can transmit a read request to a
slave, and then clock data out of the slave. The list
below outlines what software for a slave will need to
do to accomplish a standard transmission.
Figure 25-18 can be used as a reference to this list.
1. Master sends a Start condition on SDAx and
SCLx.
2. S bit of SSPxSTAT is set; SSPxIF is set if
interrupt on Start detect is enabled.
3. Matching address with R/W bit set is received by
the Slave setting SSPxIF bit.
4. Slave hardware generates an ACK and sets
SSPxIF.
5. SSPxIF bit is cleared by user.
6. Software reads the received address from
SSPxBUF, clearing BF.
7. R/W is set so CKP was automatically cleared
after the ACK.
8. The slave software loads the transmit data into
SSPxBUF.
9. CKP bit is set releasing SCLx, allowing the
master to clock the data out of the slave.
10. SSPxIF is set after the ACK response from the
master is loaded into the ACKSTAT register.
11. SSPxIF bit is cleared.
12. The slave software checks the ACKSTAT bit to
see if the master wants to clock out more data.
13. Steps 9-13 are repeated for each transmitted
byte.
14. If the master sends a not ACK; the clock is not
held, but SSPxIF is still set.
15. The master sends a Restart condition or a Stop.
16. The slave is no longer addressed.
Note 1: If the master ACKs the clock will be
stretched.
2: ACKSTAT is the only bit updated on the
rising edge of SCLx (9th) rather than the
falling.
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 01, 2014, 07:03:14 pm
Generally, the (i2c) isr is a state machine. You can look up Philips' 8051/ARM chips to see how that works and what states are involved. Atmel (even for the AVR chips) has great documentation on that as well.

Code: [Select]
WaitMSSP();
I would suggest that you think really hard about deploying loops inside of an isr.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 01, 2014, 07:32:35 pm
When my code restarts transmitting after address match and correct ACK, it is 5-seconds later, that I resume sending Master to Slave.

After the initial Addr and *W bits are sent by Master and *ACK is cleared to 0 by Slave, giving ACK properly.
After this Clk immediately returns to logic 1, as does the Data pin.

Is this is because I set the Master MSSPCON to 0x38  which enables the Clk as well as setting the 2nd MCU to Slave?
Does enabling the Clk cause trouble when configuring the mode to I2C Slave?

After 5-seconds  after Addr match ACK, I let transmission resume. However  it  won't begin unless I begin code with
   RSEN=1;
but  this generates a start condition.
 
The Result: The first clock/data bits initiate a Start Conidtion, then 9 clocks immediately follow, sending the correct byte to be transmitted to the Slave followed by the *Ack clock bit..but  but the Clk clocks in a "1" bit,  shows Ack bit=1, remains high!

Do I need to resend again the Addr and *W bits, or add some other handshake, something to properly restart the byte transmission after Addr is Ack'd:
 
Perhaps, In Master's code after Addr match ACK:

Wait2SendByte:
   if (ACKSTAT != 0) goto Wait2SendByte; //Checks that ACK=0 has been sent by Slave
    SPPBUF=byte; //Do I need this code sequence before each of the new bytes are sent?

What do I need to do to handshake to resume transmission? 

Is it the problem that I enable the Clk in the SSSPCON mode setup?

Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 01, 2014, 07:40:25 pm
Oh Dear! 

Thanks DannyF,  I was taught how to write C-code by Al Einstein's cousin, and he does have some real problems.

I planned to halt all Slave operations, including the periodic Slave 100uSec TMR0 ISR while examining Slave vars, then updating and finally syncing the Slave counter/timers to the Master.
In this way I can set the counters/timers to sync with the Master, receive as many vars as I need to know about on the Slave and no matter how long I spend updating the Slave, I can fix this by just sending the correct values of the timers/counters that the Master has before allowing the Slave to resume. Even if this process takes up to a millisec or so, the timers will be set to the latest values of the Master when the ISR resumes. I have to assume my Slave operations can tolerate a millisec timeout without a problem.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 01, 2014, 07:56:23 pm
I presume this 5 sec wait between address and data is important ?,  try sending the commands without the 5s wait..  slave enable clock bit =0 is used to hold the master while slave moves byte to SSPBUF  a response to a read  request .

You can do this !
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 01, 2014, 08:21:28 pm
Thanks again 22swg,

The 5-sec wait just to see initially in debugging if I had my code right.

The fact is, I donno what to do next codewise for a happy handshake,  to correctly to send the Slave more bytes and have them accepted.

Here's what is going on on the Master's side of the fence:

void i2cwrite()
{

 if(SSt==Init) // i2cwrite() Invoked immediately by main() on startup after a few seconds warmup delay, SSt=Init; i2cwrite();
  { SEN=1;         // Send start bit

    WaitMSSP();    // wait for the operation to be finished
                           //Slave Addr = 0x12
    SSPBUF=0x12;   //0x12 WRITE Send Slave Address+WriteCmd

    WaitMSSP();
    if(ACKSTAT==0) //ACKSTAT=0 if Nack=0(ok) sent by slave
     { SSt=Begun; //Now my main() code waits 5 seconds for me to see the results on the scope
     }
  }
                                     //There is no other code in main() except calling i2cwrite to start with and then after 5-seconds again.
 else if(SSt==UpDtSlv) //After 5-seconds, in main(), SSt =UpDtSlv; i2cwrite(); //Now begins byte transmission Master--->Slave
  { RSEN=1;
    WaitMSSP();
    SSPBUF=0xAA;  //1st test byte sent to Slave, but Ack bit stays at "1" at 9th Clk

    WaitMSSP();
   
    SSPBUF=0x55;  //2nd test byte sent to Slave, but 9th bit shows Data=high before Clk 0--->1, Data stays high Clk=1

    WaitMSSP();

    for(i=0;i<4;i++)  //4 more test bytes are presumably being sent to Slave
     {
      SSPBUF=i; //  I can see these bytes clocked out, being sent properly to Slave, Clk and Data waveform perfect 400KHz baud
                       //  But ACK = 1 !!!!
      WaitMSSP();
     }
    PEN=1;         // Send Stop  ....This works perfectly, I can see the Stop Condition clearly on the scope

    WaitMSSP();
    SSt=SlvUpDtd;  //End of test, Slave has supposedly been sent some bytes..probably been sent instead to the bit bucket.
  }
}

Title: Re: Help Me Continue My I2C
Post by: 22swg on August 01, 2014, 08:51:35 pm
My I2C Master (PIC24F)  to request a byte from a PIC slave ...  Now you will see immediately c my 'C'  is that of a 4 year old... but it seems to work.. :-[

void I2C_req_from_PB()
{
        I2C_start_W(LCD_BP_addr);  // start with W bit
        I2C_sendB(0xF7);                    // command
        I2C_sendB(0x99);                   //  command  this sets up a response condition slave waits for read request
                                            // more commands here
        I2C_endtx();                             // send stop
        I2C_start_R(LCD_BP_addr);    send start R
        I2C1CONbits.RCEN = 1;          // turn on RX
        while (!I2C1STATbits.RBF);      wait for RBF
        inkey = I2C1RCV;                  // save RX
        I2CNak();                               // send Nak
        I2C_endtx();                          // end
       I2C1CONbits.RCEN = 0;         // probably not needed
}   

void I2C_start_W(char device_addr)
{
         I2C1CONbits.SEN = 1;                                   // Set start bit
         Nop();
         while(I2C1CONbits.SEN){}        //
         Nop();
         I2C1TRN = (device_addr << 1) & 0xFE;                       // send (slave + write bit )
         Nop();
         while (I2C1STATbits.TRSTAT) {}                            //
         I2Cackstat();
}

void I2C_start_R(char device_addr)
{
         I2C1CONbits.SEN = 1;                             // Set start bit
         Nop();
         while(I2C1CONbits.SEN){}        //
         Nop();
         I2C1TRN = ((device_addr << 1 ) & 0xFE) | 0x01;    // send (slave + read bit )
         Nop();
         while (I2C1STATbits.TRSTAT) {}                    //   
         I2Cackstat();
}

void I2C_restart_R(char device_addr)
{
         I2C1CONbits.RSEN = 1;                                   // Set start bit
         Nop();
         while(I2C1CONbits.RSEN) {}
         Nop();
         I2C1TRN = ((device_addr << 1 ) & 0xFE) | 0x01;           // send (slave + READ bit )
         Nop();
         while (I2C1STATbits.TRSTAT) {}                                                             //
         I2Cackstat();
}
void I2C_sendB(char data)
{
         I2C1TRN = data;                    // send control
         while (I2C1STATbits.TRSTAT) {}                                                        //
         I2Cackstat();
 }
void I2C_sendS(char sdata[], char count)
{

    int x = 0;
         for ( x = 0; x < count; x++)
            {
            I2C1TRN = sdata
              Nop();
            while (I2C1STATbits.TRSTAT) {}                                               //
            I2Cackstat();
           //DLY10u();
        }
 
}
void I2C_endtx()
{
              I2C1CONbits.PEN = 1;             // Set stop bit
              Nop();
              while(I2C1CONbits.PEN){}
              DLY10u();
}

void I2Cackstat()
{
         if( I2C1STATbits.ACKSTAT )
   {
           I2C1CONbits.PEN = 1;    // Set stop bit
           LATAbits.LATA0 = 1;   // ERR led on
        }
         DLY10u();
}

void I2CInit()   // for a PIC24FV16KM302 ?
{

   I2C1MSK = 0;               // set this controller's device address
        I2C1CONbits.I2CEN = 1;      // enable I2C module
   I2C1CONbits.A10M  = 0;     // I2C1ADD is a 7-bit slave address
   I2C1CONbits.DISSLW  = 1;        // Disable slew - 0 for 400 kHz up enable slew rate
   I2C1CONbits.SMEN  = 0;           // No signal conditioning
   I2C1CONbits.GCEN = 0;     // general call for slave mode only
    I2C1BRG = (8000 / (2 * 100)) - 1 ;    //
     

}
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 01, 2014, 09:00:40 pm
Thanks Again 22swg!

The problem I think is at the Slave, your example shows what the Master is up to. In my code, the master correctly sends the bytes out, although with any handshaking, as proven by a scope of the process.

The problem is that the Slave is not ready/ does not have the  correct code to receive any bytes.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 01, 2014, 09:14:06 pm
This may be of help 
 
http://www.microchip.com/forums/m566862.aspx (http://www.microchip.com/forums/m566862.aspx)

but for different PIC !

Back to swat my own bugs.......
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 01, 2014, 09:23:38 pm
Are these two PICs on the same board?
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 03:43:50 am
Yes, both chips are on the same board, separated by approx 5-in.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 10:14:28 am
Bugs in Microchip Firmware?  The chips I have are Rev 2 16F886 and silicon errata does not explain this anomalous behavior I notice, although there are some issues mentioned of bits being incorrect with the MSSP module in some TMR2 related non-i2C operation.

I've gotten the i2C to work ..sometimes. Seems even independent of i2c baudrate to a great extent, so it is not a coding problem. Sometimes it will transfer all six bytes and sometimes it will stop at the second byte with the problem of not issuing an acknowledge of bits sent correctly.

My software checks for (ACKSTAT==0 means ACk issued showing correct transmission) before I continue to the next byte to be transferred. There are no ISR's running. The whole transmit receive code is withing the TMR0 ISR, an although it overflows the 100uSec TMR0 max interval sending 6-bytes, the ISR routine does not exit to service the recurring T0IF during the i2C code on the SLAVE side, although the Master TMR0 IRQ does run correctly and on time, interrupting the transmission-receive before/after a byte is being i2c sent/received, but as i see on the scope, never during the clock-data sequence of a byte being transmitted-received by i2c.

I can see on my 200MHz scope that there are some narrow upward going small spikes from ground, that is, appearing near ground, sometimes even approaching up to 1.5V, but always these spikes are between data pulse trabsistions. These glitches are always on the i2c Data line, not the clock pulses. I am using 1K pullup resistors at the Slave cbit3:4 pins and there is ample bypassing of the power supply pins(.1 uF ceramic cap between VDD-VSS pins and 1000uF electrolytic on the +5V busses VDD-VSS) and no, scoping the VDD +5 doesn't show noise. There is no other noisy hardware switching circuits nearby or active on the breadboard which has a 7805 mounted on it for the +5V.

The whole circuit  is constructed on a rather new, plug 5-wires each side of each chip pin generic common Chinese breadboard with very good quality tinned copper interconnects that i cut and  strip myself and push into the holes. The intermittent problem is showing that it is not sensitive to my banging on the breadboard, even with a screwdriver handle. So, not bad mechanical connections causing a problem. 

Haven't tried using twisted pair interconnects between the 5-in wires between i2c pins or series damping resistors or slew rate control. Problem will happen even with 7-uSec++ Clock Hi/Clock Low periods. I tried setting SPPADD to 0x08, 0x12,0x22, 0x44 values to slow down the clock with same results.
 

I haven't got a clue what is causing this hardware problem, but my scope does not show the bits received at the Slave to have any strong ground bounce or overshoot on cbit3:4 during the clock intervals.

The spec sheet itself is a little goofy for the i2C. It says the baud rate can be set up for only three speeds, 100K, 400K and 1Mhz clock but the back pages AC specs show clock and data timings for only show with 100KHz and 400KHz hold times, setup times, etc, yet the goofy way the speed is set results in using an odd formula using the SPPADD (address) to set.

i2C Clock = FOSC/(4(SPPADD+1) ..obviously this formula results in many different clock speeds not getting exactly 100KHz or 400KHz with 20MHz clock Xtals.

Why in the name of the Pope's pink panties do they use the same register SPPADD to set both the address of a Slave MCU and also the clock speed of the Master of the I2C bus.

I can see that the Master sends the correct bits for each transmissions and the databits  are not overlapping the clock.

Seems to me it should be easier in this world to build a small robot using several MCU's working together Gung Ho!

I should have quit while I was ahead, after long since managing to getting two or more LED's to blink. Now I've missed my Yoga class twice and my food is burning on the stove, my boyfriend has fallen asleep snoring on the couch and I really should be on the beach catching rays and twinkling my toes to tickle the sand crabs in the wet sand. C-Language and MCU's are the shattered shrill voice and jerky arms of the devil hisself.
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 02, 2014, 11:48:29 am
Yes, both chips are on the same board, separated by approx 5-in.
Why do you need two chips? You need more power but the 16F886 is the only PIC you know? I have seen this a lot. People use two controllers because they know them and run into a world of pain trying to get them to communicate. The best solution is to use a faster/better equiped controller for your circuit. Getting the I2C to work is just the portal to the world of pain you are about to enter... For your own sake: use a bigger controller!

About getting I2C to work as a slave: I'm sure Microchip has example code on how to do this. Did you follow that or did you try to come up with your own? Starting from a working example is much easier when dealing with I2C. There are all kinds of situations that needs to be dealt with (unfinished transfers and so on).
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 01:42:29 pm
I am trying to build a robot with 4 motors and they need PWM and their own A2D to manage things and maybe if they have their own brain to do their calculating things it is better than one idiot trying to control everything by itself and there is not enough PWM (only 2) on one chip, need 2 more  and the bigger chips  with lots of pins cannot be breadboarded without special expensive custom boards that wont fit into the box wiring wise so easily so it saves a lot of expensive cables and wire is more expensive than Dinner for Four at FatsoLand,  and I am familiar with this chip, it is the only one I've tried to save the world with so far, and modular seems better a approach to divvy parts and brains up. Even octopuses work this way.

The problem was not with sample code with microchip, although their explanation of operations is rambling, vague, and usually deals with a Master talking to a Slave such as an A2D chip or something that knows how to respond..anyway the problem seems to be with the chip itself since the datasheet is goofy and yeah it works sometime so I am thinking firmware wacko at fault.

If Microchip had any brains about explaining things they would realize that chip to chip i2c communication is essentially a conversation, so it should be explained with by showing Who's on First and What's on Second with two columns transacting in a parallel matter in explanation. For the life of me, their diagrams and repetitive explanations tell me exactly what occurs but I cannot posit  whether it is Master or Slave or my code or firmware, if I only knew what exactly the who's that is doing what in their explanations, Slave or Master or firmware or my c code.
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 02, 2014, 01:56:04 pm
Then buy a bigger chip on a module with pin headers (like the ones from Olimex). Maybe even look for an ARM controller. I have been messing with PIC like controllers 20 years ago but I would have moved to an ARM controller instantly if they where available back then. More power and I/O makes everything so much easier that I really don't understand why people keep tormenting themselves by messing with ancient 8 bit controllers. If you invested the time you wasted on getting I2C to work into learning on how to use a bigger more modern controller your robot would probably be running around already. It just takes a little bit of curage to go out of your comfort zone and create a new comfort zone.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 02:27:44 pm
I don't know Arm from Elbow about these pre-fab jungle-chip custom boards. It would take me a year to get to know how they work, and another year to install the software and spend lots of money to get compiler software that works easy and well, not to mention then how to learn their own zillions of oops and gotchas.

The idea is that with breadboards, if I blow up a chip I don't have to buy another expensive board and wait days or weeks to get, just plug in another chip that cost me less than a Big Mac. I can program the PIC in 15-seconds without any complicated software IDE, write code in C using a simple editor and keep things simple enough for the simple mind I seem to possess but slowly losing to MCU complications.

It is better to trust the devil you know than the devil you don't.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 02, 2014, 03:17:36 pm
Where to start .... Moving to a bigger better chip may be the way to go as better debugging is available , but can I see your frustration, when I did my I2C slave I used a monitor subroutine that displayed on a small serial lcd ,,,  then I could see the SSPSTAT  bits and built a "state machine" around that... eg first interrupt / byte is start and address h'09 , [ state 1]  master wants to chat !  next Interrupt was  h'29 [state 2] master wants to write a byte ( in this case a command ) put byte into buffer ... next int h'29 , more commands, next interrupt  h'30 master has stopped chatting ... run the command . I coded 8 states and a bit of error handler.  so it can be done and still keep your hair ...

"sometimes works " would suggest timing problem, my slave was running at 16Mhz , ISR needs to be ahead of the I2C bit stream... also C will be slower than an asm code.

You can put a larger chip on a BB , all my PIC24FV projects start mounted on a 44 pin BOB that can go an a BB .

Did you look at the PKSD zip file on the MC forum link ?
     



Title: Re: Help Me Continue My I2C
Post by: nctnico on August 02, 2014, 06:35:23 pm
How about using an Arduino board? If you google for 'Arduino robot' you'll get thousands of projects.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 09:39:59 pm
Thanks again 22swg,

BTW, what does those 44-pin PIC  DIP (I assume only with 24FV chip installed?) cost ea, easy to buy?, ebay it?
Is the 24FV got  specs and ease of use compared to an ARM? What about the cost of
a user friendly competent C compiler, debugging?

I have had no problem interfacing the 16F886 to a i2C 24F512, reading or writting, wasn't too hard, and reliable, the 512K SEEPROM was nothing like the difficulty I am having is connecting to another 16F886 Slave MCU.
I could not log on to the MC forum link, said i don't have permission to access that server?
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 09:58:41 pm
Thanks for your suggestion, nctnico. Fact is that a year or two ago I bought one, an ATMEGA2560A genuine Arduino board, it is still sitting on my shelf. The problem with that board is it's size and 3.3V I/O and A2D which I find clumsy to work with. it is so big as to only fit into a very large project. Also didn't like the C-language scaled down to beginners Arduino version, seemed too specific to the Arduino and made it slower and created larger code.
Took me hours to install the IDE software. Also quite a few bugs with the silicon itself and quite a few errors/mistakes in the spec sheet and the IDE.  Also much slower to program using the USB interface.

 Couldn't use the debugger/ emulator because the Version of the IDE didn't support this chip. A bothersome thing was trying to make connections to the connectors, really clumsy and slow and unreliable with single wires and so needing really big sizes IDE connectors to get too many pins that I don't want to use bled out to a project or motherboard.

 I don't like the idea of "shields", too much like staking Lego toys,  but more expensive, hard to come by, and makes the stack of wires even taller and thicker.

The board itself, It was also 10x more expensive compared to a single PIC chip and I was always scared that I would soon quickly fry a I/O pin or the chip itself with a slip of probe or a mistake on a breadboard.

On the plus side it was about 3x faster with some code and had a lot of RAM and code EEPROM space to work once  I had access to use just ATMEL's C by buying  an expensive JTAG 6-pin to USB cable so as to not use at all the Arduino bootloader.

Finally the technology of the very tiny hi-tech pin to pin spacing of the ATMEL chip meant that I could not make any PCB's myself to be able to solder in the chip, so I would have to settle for buying the chip on a header or have to complete a project by buying another board to have one spare to work with.

 
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 02, 2014, 09:59:06 pm
 :)  Afraid I'm of the DIY school ... PIC was ~3 GBP from farnell  bob was <2 from hobbytronics ,  rest is history.. just need a good iron .5mm bit , flux pen and solder mop ... Oh and magnifier !

Its not well thought of by some posts on the net  but I'm happy with MPLABX XC16 and PicKit3 , PC is XP.   

Think you should persevere with 886  what was the clock  Mhz ?

http://www.hobbytronics.co.uk/prototyping/smd-adapter-boards (http://www.hobbytronics.co.uk/prototyping/smd-adapter-boards)

Attached   ...   
Title: Re: Help Me Continue My I2C
Post by: bingo600 on August 02, 2014, 10:23:12 pm
Afsik. The arduino mega is 5v, not 3v3.

Don't go Down the evil Pic route  ;)

Use a Micro with a Real free compiler , ie. Avr or arm.

/Bingo
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 10:35:58 pm
Thanks for the tip on buying the chip and  bob, 22swg.

Any link to a good enough soldering iron station to do the job with the bob?



 I am using the 16F886's with 20MHz xtal.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 02, 2014, 10:43:40 pm
Is the 886 in the bin ?  :(  , Farnell have minimum order  :--, my iron is just a standard 12w Antex .. have you got a steadu hand ?  send me a PM may be able to help ...
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 02, 2014, 10:57:45 pm
Bingo600

Thanks for the advice and reminding me that I do have a 5V Arduino board..

 I've been looking a few ARM 3.3V MCU's and I forget the ATMEG2560 was a 5V device.

What do you use software and hardware breadboard wise to work with ARM?

Can you actually say that you have found something as easy to use, reliable, as bug-free as PIC chips, a competent IDE that allows easy compiling, chip programming, compared to PIC.. as easy to use?
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 03, 2014, 12:16:28 am
Most NXP ARM controllers are 5V tolerant even though they use a 3.3V supply. The documentation is good and judging from the comments from others the LPCExpresso software is easy to use.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 03, 2014, 03:02:57 am
Thanks again 22swg!
Yes I have a very steady hand.

I am a little uncertain on how to continue with the PIC16F886 based idea, my code uses now, compiled 90% of the 8k available and I can see that I am not getting anywhere troubleshooting the i2c problem. I got to reread the i2C interfacing again to catch what is wrong. The Master--->Slave dialog is only succeeding if getting a complete byte transfer burst only once in approx.  any 10-seconds of operation which is entirely,  to put it simply, goofy.

I have the option, if not perhaps the good sense, to try to use PIC16F887's and use my own 4-wire communication protocol which I have already spent weeks perfecting several years ago. Having a two I/O pins for irq trigger and dedicated state machine control signals for handshake dialog and then the other two other pins, Serial Data/Serial clock pins makes the communication job much easier and independent of interrupt complications and there is then no handshake ambiguity or uncertainty of which byte or bit is which and what direction they are going in.

I can see the advantage of using a single chip, but the idea of remotely locating the individual chips right near the motors is much more compact and sensible for the large currents, sensors and drivers involved, but I still embrace my goal and like the idea of a  centralized MCU Master-Slaves type of operation and control.

I can see it will be some while before I catch up with the robotic work being done in Japan or even the sleep I've lost.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 03, 2014, 08:21:26 am
The distributed intelligence , for even 'simple' robots would be the way I would go, perhaps I2C is not the method , dare I ask if you looked at SPI , not been there but has higher speed and 4 wires...  Dogged persistence must be in EE blood...  :-+



 
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 03, 2014, 10:24:32 am
I wouldn't use SPI. I2C is a bit more rugged in noisy environments.

@SuzyC: I'd start with a single controller. Creating a distributed system requires careful partitioning of a system. You'll find you often have to share much more data than you initially think which increases the amount of communication between various CPUs.
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 03, 2014, 11:17:08 am
Quote
Can you actually say that you have found something as easy to use,

Ease of use is highly personal, and in the case of PIC, I would argue that on some respect it is quite difficult to use, but its simplicity (primitive?) helps.

Quote
reliable, as bug-free as PIC chips,

Its simplicity.

Quote
a competent IDE that allows easy compiling, chip programming, compared to PIC.. as easy to use?

I would argue that either MPLAB or MPLAB X is the opposite of a competent IDE. Because of that, I don't use PIC18 (for a lack of good IDE). For 10/12/16 chips, I use hi-tide, and for 24f chips, I use emBlocks.

Going to an avr would add no meaningful value.

Going to an arm offers you more flexibility, better IDEs (CoIDE or either Keil / IAR), more hardware debugging capabilities and an upward path. However, it is considerably more complex to code than an 8-bit chip.

As to your trouble, I do not know of a i2c slave that is not coded via a state machine. NXP used to have lots of examples for their LPC21xx chips that demonstrated how that can be done - those code pieces are directly portable to a PIC. If you look at most of the I2C hardware implementations, you will see a state machine in them - STM8 / STM32F for example.

A centralized one-chip solution doesn't fit your application so you have to figure this (I2C slave) out. No way around it.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 03, 2014, 12:49:54 pm
My little grey cells have been pondering during a spell down the allotment....  :-+   , take the I2C comms away from the slave PIC (where the bottle neck is ) and put in an I2C port expander   ... I have used a MCP23008     >:D  ( 8 hard wired  address possible )  lots of possibilities if you increase the wires to 5 ,.,., logic 5V, Gnd , clock, data, interrupt (to master)  TX as many bytes as you like, read the slaves data pins (may be a bit tiresome ), give you back some memory ... 
Title: Re: Help Me Continue My I2C
Post by: senso on August 04, 2014, 12:52:46 am
But Microchip has like a million different parts, you can throw a dsPIC in DIP-40 and have a much faster core, lots of timers, pwm, fast ADC, and a LOT of goodies, the compilers might be or not crap, but they are free-ish, download them and buy a PIC designed in this century.
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 04, 2014, 10:38:30 am
Going to an arm.... However, it is considerably more complex to code than an 8-bit chip.
Nonsense. It is just as easy or difficult. An ARM microcontroller is just like any microcontroller: a CPU, memory and peripherals. There is nothing magical about it and no high wall to climb. And you know it (LPC21xx are ARM microcontrollers after all):
Quote
NXP used to have lots of examples for their LPC21xx chips that demonstrated how that can be done - those code pieces are directly portable to a PIC.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 02:30:40 pm
Ok, I've go this code to work half the time. The other time the first test byte sent by Master is not  acknowledged *ack =0
but Addr is *ack=0 and so Slave address match has been detected ok.

 I know when it works and when it's not working, I can see it clearly on the scope.

//And I don't have a clue whatsamatta


//----------------------------------------------------------------------MASTER----------------------------------------------------------------
main()  //most initialization code of chip no shown, not the problem
i2creset();
  i2cinit();  //Sets SSPEN i2c lock TRIS's cbit3,cbit4 as inputs Clk is set on upon setting SSPCON to Master Mode = 0x38
   HmS1=0;
  SSt=Init;
  i2cwrite(); //Master sends bytes to Slave with this routine
start:; //---------------------  START  ------------------------------
  if(SSt==i2cerr) //Alas, most often the case!
   { SSPEN=0;
     i2creset();
     i2cinit();
     SSt=Init;
    HmS1=0;
    i2cwrite();
   }

 else if (SSt==SlvUpDtd) //if everything went well
  { if(HmS1>9) //restarts every second
      {
        SSt=Init;
        HmS1=0;
        i2cwrite();
      }
  }
  goto start;


void WaitMSSP()  //Antifreeze test for SSPIF.     this routine code exactly the same in both Slave and Master
{int k1=0;
  W4IF:
   if(!SSPIF) // while SSPIF=0 stay here else exit the loop
    { if(k1<65535)
       { k1++;
         goto W4IF;
       }
      else
       { SSt=i2cerr;
       }
    }
   SSPIF=0;       // operation completed clear the flag
}

void i2cwrite()
{
wait4ClkHi:

 if(cbit3==0)goto wait4ClkHi; //Wait first for Slave Clk to be ready

 if(SSt==Init) //it is always Init when called by main()
  {
    SEN=1;               // Send i2C Start Condition first
    WaitMSSP();       // A start bit sets SSPIF
    if(SSt==i2cerr)goto i2cWXit; //anti-freezeup
                              //Slave Addr = 0x12
    SSPBUF=Addr;   //0x12 WRITE Sent to Slave Address+WriteCmd


Wait4Ack:
    WaitMSSP();      //Wait for Ack
    if(SSt==i2cerr)goto i2cWXit;
    if(ACKSTAT !=0) goto Wait4Ack; //ACKSTAT=0 if Nack=0(ok) sent by slave

    SSPBUF=0xAA;  //test byte

Wait4Ack1:
    WaitMSSP();
    if(SSt==i2cerr)goto i2cWXit;
    if(ACKSTAT !=0) goto Wait4Ack1;

    SSPBUF=0x55; //test byte

w4b3:
   WaitMSSP();
    if(SSt==i2cerr)goto i2cWXit;
   if(ACKSTAT != 0)goto w4b3;


   for(i=0;i<4;i++)  //4 bytes sent to slave
    {
      if(i==3)
       { SSPBUF=0xA5; //Always the last byte sent to Slave to verify sequence of bytes completed ok
       }
      else SSPBUF=i;  //Just a test byte at this point
w4b4:
      WaitMSSP();
      if(SSt==i2cerr)goto i2cWXit;

      if(ACKSTAT !=0) goto w4b4;

    }
   PEN=1;         // Send stop bit
   WaitMSSP();
   SSt=SlvUpDtd;
  }
goto i2cWExit;

i2cWXit:;
SSPEN=0;  //Error in Master to Slave Session, Reset the whole thing!
SSPCON=0;

i2cWExit:;
}
//--------------------------------------------------MASTER Code Ends -----------------------------------------------------------------------------

//--------------------------------------------------Slave Code Begins (located inside inside ISR)---------------------------------------------

interrupt int_server(void)   
{
T0irq:
if (T0IF)      // TMR0 overflow flag, if set triggers IRQ  TMR0Clk=Clk/2
 { TMR0=17;    //Comp needed to calibrates timer for exactly .1uS/IRQ.
   T0IF=0;       
   pt1_mSec++;
   pt1_mSec1++;
   pt1_mSec2++;   
//---etc code to udate ten_mSec, Hun_mSec counters ...code not shown here
XitTimer:;
 } //------------------------------------------------End of TMR0 ISR--------------------------------------------

if(SSPIF) //set by ADDRESS MATCH, Start or Stop  Start Bit Detected
 {           //CPK is set high by main()
              //Should sends Ack=0 to Master and Sets SSPIF  twice on Master, (once already set by start bit)
   if( (SSt==Idle) ) //always set by main()  to Idle to start i2c conversation
    {
      if( (SSPBUF & 0xFE)==Addr) //*Ack =0 always set by slave if Addr match  Addr = 0x12
       {           
         SSPIF=0;
         BF=0;
         SSt=TxRx;  //After an i2c Addr match 6 bytes follow to be received by this Slave code
         Din[5]=0;  //Must ==0xA5 as a check for valid reception of all bytes sent by Master
         bn=0;       //reset incoming byte counter bn
       }
    }

RecMore:

   if(SSt==TxRx)
    {   
         CKP=1;     //enable reception
W4B0:
         WaitMSSP();  //SSPIF set when buffer is full, Slaves expects a byte
         if(SSt==i2cerr)goto i2cerrxit;
         if(BF==1)    //Byte has been received so SPPBUF is full
          {
            Din[bn]=SSPBUF; //grab the byte and save it in a small array
            CKP=0;          //stretch the clock b4 acknowldege
            if(bn<5)bn++;
            if (bn==5)
             { if ( Din[bn] != 0xA5) //Check for valid transmission sequence
                { CKP=0;
                  SSt=i2cerr;
                  goto i2cerrxit;
                }
               else
                { CKP=0;
                  SSt=Begun; ///Correct Master-Slave session so set SSPI state to Begun = Success
                }
             }                 
          }

         if(SSt==TxRx)
          { CKP=1; //Re-enable SClk
             
          }

    }
goto Xiti2c;

i2cerrxit:  //no error management code yet.  Main just retries again from the start

Xiti2c:
   SSPIF=0;   //No code for Start Condition, just trying to catch the Addr match and work from there
   goto ExitISR;
 }

ExitISR:;
}
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 02:41:21 pm
Here is the Slave main() for the code above
.......etc
 SSt=Idle;
 CKP=1;      //enable clock line
 SSPIE=1;    //enable SSPI irqs on start stop buffer full
 SSPEN=1;    //Enable i2c
  Sec1=0;   
  HmS1=0;
start:; //--------------------- SLAVE START  ------------------------------
  if(SSt==Begun) //if there only was such a thing as success
   { blink=1; //Fast Blink LED means ok session
     CKP=0;
     SSPIE=0;
     SSPIF=0;
     if(HmS1>20)
      { HmS1=0;
        CKP=1;
        blink=2;
        SSt=Idle;
         SSPIE=1;   //do it again and again
      }
   }
 
  else if(SSt==i2cerr)
   {HmS1=0;
     SSPOV=0;  //Else error   Take it from the top again
     SSPIF=0;
     CKP=1;
     SSPIE=1;
     SSt=Idle;
   }
goto start;
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 04, 2014, 04:19:34 pm
"half the time "  Thats better than it was  :)  ... I found in I2C asm  the "state machine" made life easier , each interrupt .. start , buffer full, read , write, restart , stop , had a sub to process the data ,
Am i wrong but you seem to enter the ISR for the whole I2C  packet ... anyway  I started to look at my asm code and move it to XC8 , (new to me) to see where Slave problems arise..  I have got to where the ISR fires up on a start ....   


 

   
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 04:32:11 pm
Thanks again 22swg!

The code has a if(SSt=TxRx) that is entered initially after an address match and so gets the first byte and thereafter only on an IRQ from SSPIF.

I have an LCD readout on the Master and I kept score.  Each pass on the main() loop the i2cwrite()  (Master to Slave) is invoked with either success or failure and I got 278 good results 1003 failures over 6.5 minutes, i2cwrite() gets a hit every loop that shows a result of the last ry and it gets invoked about 3 times a second in main().
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 04, 2014, 05:02:26 pm
What happens if you lower the data rate of the I2C master to 1kHz? If the communication works perfectly at a much lower rate you can conclude that your software is too slow. Or there might be a hardware problem due to the I2C signals getting distorted by a pull-up resistor which is too large.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 05:11:29 pm
Thank you DannyF for your advice!

I can't help but compare to PIC, offering DIP packaging, on serial in-circuit programming, so plugging it in/into a programmer is a snap.

I have not found powerful ARM NX chips on a tiny PCB header to plug right into a project or that can be easily wired for use with a breadboard so common to get that is offering just the basics, the chip with bleed-out for all pins and a place for the clock xtal and caps and programming the chip. For me, In Situ, socketed chips or module On-chip programming is also a must.  The IDE/compiler software you recommend is probably expensive? Needs Linix?

license (£3,349.14 = $ 5412) of KEIL MDK500 for code size >32KB

....Found this comment on a forum also:
The SoftDevice stack is precompiled so it does not count into the 32k limit of the free version of Keil. Most applications will actually fit inside 32k because of the architecture and SDK that Nordic provides. If you need more than 32k, there is always Eclipse and GCC.
Some fellow named Bastiaan (Nov 20 '13)


And would not so much ARM power have a steep learning curve to understand how the chip works (or doesn't in gotchas)?
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 05:31:06 pm
Thanks for your help ntcnico!

The question is, what is the max. latency in i2c specs for the i2c receiver to respond before the transmitter(Master) 9th i2c clock is going to  go hi? and make a go/no go decision?
My scope shows i2c clock and data rise/fall times of approx 10nS or better. Besides the Addr match always works and sends *Ack.

As I have stated in a previous post, I have tried Master clock speeds as slow as approx many uSec for each hi and lo period using the i2c formula i2c Baud=FOSC/4 (SPPADD+1)  setting SPPADD=0x44) and it did not make any difference at the time.

In fact the approx i2c 1.5uSec clock (SPPADD=4) yielding  a clock hi and lo period of approx 1.5 uSec  seems to work just as well as any other slower clk I have yet tried.

I haven't had the good sense yet to try even snail so slow clock speeds to troubleshoot the problem yet.

I know the Slave ISR can respond to a SSPI IRQ in <15 uSecs and the scope shows that the i2c byte was Tx'd correctly to the slave. If there were no response from the slave once the i2c byte fills the Slave SSPBUF buffer, that would be the problem, but the i2c firmware automatically clears ACK once the buffer is full after and Addr match and then after the Slave buffer is filled again with an incoming byte.

The fact is that the i2c always sends a correct Addr match *Ack, it does this automatically, now immediately after getting the SSPIF set and reset, the Master sends a byte and my Master code WaitMSSP() has a loop that waits up to 65535 iterations of an integer k1++; goto incl., just waiting checking for the SSPIF flag to be set before calling off the game(at least >.1 second before the referee yells Foul!).

Doesn't this code mean that there is a very patient Master waiting for an Ack=0 after a byte sent to the Slave?
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 06:06:11 pm
SPPADD=0x4;

Latest score:   Successes: 5300   Failures: 17536

Now I'm going to see if slowing the clock speed with my changed code.

"The hurrier I go, the behinder I get!" might apply here.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 06:15:25 pm
 :) ;) :)Changed SSPADD for setting i2d clock from 0x4 to 0x8

Score Failures: 55 Success: 38

Changed SSPADD to 0x10

Score Failures: 42 Success: 103

Changed SSPADD to 0x20

Score Failures: 1 Success: 25000  //the one and only error occurred at startup but takes 800uSec for 6-bytes!

Now to find the sweet spot!

Changed SSPADD to 0x18
Score Failures: 6 Success: 50000  //Some errors occur after startup with several seconds between them

Still same SSPADD, 0x18 but just Reset Master and the Slave processor, test 2
Score Failures: 0 Success: 50000  //Just no errors
Still same SSPADD, but just Reset Master and the Slave processor, test 3
Score Failures: 4 Success: 65000  //Just a few errors

Changed SSPADD to 0x14
Score Failures: 20 Success: 1698  //Some errors occur after startup with fractional seconds between them

Changed SSPADD to 0x16
Score Failures: 10 Success: 9363  //Some errors occur after startup with fractional seconds between them

Changed SSPADD to 0x17
Score Failures: 4 Success: 10000  //Some errors occur after startup with fractional seconds between them

//seems to be a pattern here.

And this years IgNobel Prize for Code and i2c Troubleshooting goes to   nctnico  thanx!
 :)  ;) ;) :-+ :-+ :-DMM :-DMM :scared: :scared:
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 06:29:17 pm
Thanks to everyone!

Now I gotta figure out how to get the Slave to send back the bytes I need to the Master!
I hope it will be easier.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 04, 2014, 07:57:02 pm
As a matter of interest what pullup value are you using on clk and data ? 
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 08:11:03 pm
22swg:   Thanks Again for your great help and encouragement!

I am using 1 k for both Clk and Data
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 04, 2014, 09:27:19 pm
-seems to be a pattern here-

I tend to think that it is a lot more important to know why some numbers worked better than others, not just that some worked better than others.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 04, 2014, 09:49:24 pm
I would consider that too low , normally I use minimum 2k2  ...    this what clk baud should be   • I2C Master mode, clock = OSC/4 (SSPADD +1)
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 10:06:04 pm
If the problem is with pull-up resistors, then 1k should be better for high frequency performance than 1K, unless the problem is not risetime to slow but risetime too fast with overshoot so 2.2K resistors may benefit to lower risetime while not affecting groundbounce.

BTW, I have been looking at 24FV processors and notice that only 3 PWM's per chip. Leaves me with one PWM missing. Otherwise the 32K program mem, 2k RAM 12bit A2D and multiple timers, 16MIPS 5V operation  etc and price seem attractive, but the BOB is perhaps more costly than the PIC for each instantiation.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 04, 2014, 10:14:45 pm
I believe it will take longer to switch 5 milliamps  1k :  than 2 miliamps 2k2 ?    some would recommend 4K7 as pullups especially for 400 khz   
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 10:19:05 pm
Thanks again DannyF,

I certainly agree that engineering should be more than a binary search to precise a working circuit.

I am without a guess what the exact problem is, but that lowering the i2c baud rate does solve the problem. If seems inconsistent with the i2c specs in the 16F88x spec sheet which on one hand says max i2c clock can be 100K, 400k or 1MHz and I could not get my i2c code to start to work reliably unless I dropped the clock down to about 6uSec per cycle.

Do you have an answer to this enigma? Ever since I left my Indian Spirit Guide in California I have at present no one to ask.

My guess is that at the 1.6uS clock I was not meeting the requirements for data setup/hold time relative to clock or else the Tmin setup time between a SEN command and the SPPBUF=Byte stuffing into the chip. Yet this proves itself wrong at the send side, because I can clearly see the byte transmitted correctly by the Master on the scope.

So the problem must be on the Slave side of this game.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 10:21:45 pm
22swg, thanks for the help,

It is just the opposite, it is always faster to switch higher drive currents.  Remember T=RC and so the pullup resistor must be slowed by charging/discharging a larger input/output circuit capacitance, so the larger the current the faster the charge/discharge of any switching circuit. With open-drain outputs, the pull-up resistor only affects the risetime. The falltime is completely determined by the open-drain turn-on time of the MOSFET inside the chip.
Title: Re: Help Me Continue My I2C
Post by: mikerj on August 04, 2014, 10:25:45 pm
Have you actually checked your I2C timing on a scope?  It's possible you have more bus capacitance than you think which could be throwing the timing out.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 10:32:24 pm
Thanks MikerJ,

I have a 200MHz 4-chanese digital scope and it clearly shows a clean clock and data pulses, fast rise and fall times in the <10 nSec range with very little noticeable ground bounce or significant overshoot.  After all, I am using 1K pullups and only 5-in of wire between the two MCU's.  With the 1.6uSec hi and lo period nfg clocking, I would expect problems if I were driving 2-meter lengths interconnects, but not for 5-in open wires.

The problem cannot be rise or fall times, because these do not change with clock speed.

I do not see on the scope at 1.6uSec clock rate any overlap of clock and data, and see fast rise and fall times. Since my scope has fast update rate I should see "ghosts" of any reflections of the pulses, but I don't..looks really nice.

The data setup time and time between a Start Bit condition and the first loading of a byte into the master Xmit Buffer is a spec i must try to check out in the spec sheet.  Problem is, the specs get worse(setup and hold times are proportionally longer) with slower clock speeds(100k) and there are no specs for 1MHz clock rates.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 04, 2014, 10:43:35 pm
I only mentioned the PIC24FV  as its what I currently "get on with"  as you expect to run out of memory then perhaps I could sell you  ;)  16F1788  oooh.. 

Edit , try a 2k2....
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 04, 2014, 11:07:15 pm
22swg

From the 16F1788/9 Microchip SpecSheet:  16KW..now that is power!

Up to 16 KW Flash Program Memory:
- Self-programmable under software control
- Programmable code protection
- Programmable write protection
• 256 Bytes of Data EEPROM
• Up to 2048 Bytes of RAM

Edit 2k2  =2.2K  whatcha  do with dat?

Again 16F1788/9  are one PWM short of a full deck and the 16F1788/9 is not supported by Hi-Tech C compiler Pic 10/12/16 pro ver 9.83

If I have to upgrade my compiler I might as well lift my leg towards the PIC family and give an ARM a chance to shake a stick at.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 12:34:58 am
Tried lowering the clk, data pull up resistors to 500-ohm and also tried raising the values to 2k, both with worse results, x10 increases in random errors.

I was in error in reporting the rise/fall times, it is more like 100-120nSec 10%-90% of P-P. at the present clock speed of around 5uSec per cycle. What is remarkable is that the fall of the clock is around 200nS away from the fall/rise of the data, but also it is that  the 0--->1 of the clock is always squarely in the middle of the data pulse.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 12:39:37 am
Thanks again, nctnico

The idea of single MCU works only if there are enough PWM's on the chip. I need 4, most PICs have three.

I kinda wrap my head around using distributed processing power v. 1 powerful MCU to replace multiple MCU's for my robot.

I would rather have one idiot manage 4 morons than one moron managing four motors.

The communication to the individual satellite MCU's is mostly to boss them around, not needing them to communicate with each other, but only to Mr. Big who mostly gives them orders.
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 05, 2014, 12:45:11 am
How about using dedicated, I2C controlled PWM chips?
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 05, 2014, 12:55:52 am
You may want to try PIC24 chips - many of them have tons of pwm, with dedicated timers.

Development tools: C30/XC16, Maplab / Maplab X or emblocks (my favorite).
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 12:56:13 am
Thanks nctnico for the suggestion,

My main idea here to get this robot off the ground is to keep the circuits small in size and cost and use off the shelf parts to create small modules.  Using i2c PWM controllers does not provide the support for other optical and other sensor functions needed at each motor's location, nor does it allow me to get exact feedback of the power and rotational speed  that I might want  to get to determine the PWM required by each motor.

Now if I have 4 motors and then I must have four conversations with 4 i2c dedicated PWM controllers and then also near each motor I have multiple sensors that also must be giving me feedback, quite a busy job, quite a few wires running in all directions out/in, quite a lot of ground loop problems as well, is it such a good idea, a single MCU?  With distributed MCU's I only need to daisychain the i2c wires to control my robot and the Mr Big processor in the middle has time to think, being relieved of all the dirty work of accessing each of the sensors while also trying to calculate PWM management, speed and each motor's torque load at the same time. I simply ask the individual MCU's how they are managing the tasks assigned to them and what's the latest gossip about the situation they are in.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 01:05:41 am
Thanks DannyF,

I was just looking at 22swg's suggestion to use 24FV chips. They are 5V compatible devices but again have only 3 PWM's.

I also looked at the 32MHz PIC16F1889 which also fails at 3 PWM's.

What's left is 3.6V ARM and PIC devices and that is an interfacing problem 3.6 logic levels and also having to deal with high current brush motors giving off EMI by the bucket full.

Consider this:  One 16F886 chip has 4-5MIPS?  One 24FV PIC has 16Mips.  4 x Motors x 4 updates/calcs x multiple sensors: all by one MCU. Thinks me I might require 20MIPS?
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 05, 2014, 01:21:48 am
Since you are using the hardware pwm modules, the mcu is fully freed up -> 0mips needed.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 05, 2014, 09:26:05 am
16F1509 supported hitec ? 32Mhz  4 pwm  only 8k and short on I/O...   
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 05, 2014, 10:47:53 am
Quote
not supported by Hi-Tech C compiler Pic 10/12/16 pro ver 9.83

I was a big fan of PICC, until they turned OCG. I still have 9.60/9.63 std/pro compilers somewhere.

The new XC8 compilers are very good replacement of the PICC. They (1.12 is the one I tested) generated fast / small code even in free mode (better than the PICC std compilers).

The differences between XC8 and PICC/PICC18 are minor, mostly in fuse settings. So migration is easy.

I would suggest that you migrate to XC8 instead.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 01:55:55 pm
Thanks again, 22swg!

But this 16F1609 chip would be something to look at if it only had more I/O pins, only 20!
I need more I/O pins to use a one-chip solution.
Yes, it is supported by Hi-tech compiler.
With few pins, this means not having pins for i/o control, debugging and communication, so program development is very difficult and so much of the capability of the chip cannot be used because you must borrow from i/o Peter to pay peripheral Paul.

I would like my robot to be able, not handicapped by not having sufficient i/o. I have got now Master--->Slave i2c to work, so I have the ability for one Mr. Big chip to do something with many sensors, have some power of calculation as well as control my obedient Multiple Moron Motor Manager Modules (MMMMM)

Maybe that is where that Arduino ATMEGA2560 may come in handy if I can scale it down in size.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 02:02:06 pm
Thanks DannyF,

I downloaded the XC8 free version and installed it and was very disappointed. A large (95% of program memory used when compiled sucessfully with Hi-Tech Pro) C-source program that I had would not compile, giving me multiple "Cannot find xxxx bytes in p-sect errors".  XC8 free edition is  just crap, just like the free version of Hi-Tech Lite, gives the same low performance results because of no optimiziation. To get my source program to work I had to delete about 25% of my source code to get my source code to compile without running out of program memory, leaving me with a bloated, broken, does almost nothing result.
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 05, 2014, 02:27:35 pm
If you care about code sizes, you should try pre-OCG compilers - 9.60 is my favorite. They however have limited support for newer chips.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 05, 2014, 02:48:44 pm
Thanks DannyF.

Not limited support, no support for new chips.

That's what I am using now, Hi-Tech Pro 9.83 for PIC10/12/16, but I am wanting to use newer chips, graduate to a more powerful chip to control my robot.

So, at this point at ATMEL IDE installed and I just downloaded Kiel free edition(<32K compiled code) for ARM NX. What next? Eclipse?
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 05, 2014, 04:00:49 pm
No. More coding. The issue you have is far less of an issue of the mcu, but coding.
Title: Re: Help Me Continue My I2C
Post by: amwales on August 05, 2014, 05:16:03 pm
I had to code up an i2c slave recently.
You may find the following links useful ( this is NOT my code ) but it helped me understand it alot.

http://www.guiott.com/Lino/Display/DisplayI2C.htm (http://www.guiott.com/Lino/Display/DisplayI2C.htm)

Take a look at the i2c ISR here

http://code.google.com/p/lls-disp/source/browse/trunk/LlsDisplay/LlsDisplay.c (http://code.google.com/p/lls-disp/source/browse/trunk/LlsDisplay/LlsDisplay.c)
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 05, 2014, 05:29:47 pm
Quote
Take a look at the i2c ISR here

It utilized a state machine there. Slaves without interrupt + state machine are very difficult to do.
Title: Re: Help Me Continue My I2C
Post by: amwales on August 05, 2014, 08:45:11 pm
Are you checking and clearing the WCOL bit?

from the pic18f26k22 datasheet ( same applies for the pic16f87xa )

Any write to the SSPxBUF register during transmission/reception of data will be ignored and the write collision detect bit, WCOL of the SSPxCON1 register, will be set. User software must clear the WCOL bit to allow the following write(s) to the SSPxBUF register to complete
successfully.

Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 06, 2014, 01:46:27 am
Thanks Amwales,

I see the sample code links are working with i2c firmware is displays and that is different from i2c with another MCU.
The WCOL bit is not likely to be a problem since at this point I have only one Master, so only one player is calling all the shots.

Maybe it is a Microchip  Silicon Error:  I see runt pulse widths (approx .5uS or less) of high i2c clock pulses occasionally captured on my digital scope, but having correct amplitude and offset position in the 9-bit parade, though inside the bounds of the data pulse.

Microchip reports this problem with SPI operation in their 2012 silicon errata for 16F886/7.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 06, 2014, 02:05:30 am
Thanks, DannyF

I am coding away.

I also notice that the ATMEGA2560 has no I2C exactly, just what they call "2-Wire", said by some to work the same way, but the way i2c operational states are named and handled and 2-wire initialization requires different coding.

The newest 6.2 version of ATMEL IDE does not offer support except for compiling/programming, no software debugging or simulation/emulation in software for the 2560, so without an expensive peripheral device, some kinda "ICE" costing many hundreds $$$$, I am kinda handicapped to get code to work.

So I gotta just study my code,  for to be buying that board, that's a lotsa clams.
Title: Re: Help Me Continue My I2C
Post by: 22swg on August 06, 2014, 07:02:28 am
WCOL can be set with one master and a slave all to easily . if your setup is on BB  then you can get spurious spikes and stray capacitance, they are not the most secure of connects.
how about a bb jpg .  are you  doing any thing with WDT ?

Title: Re: Help Me Continue My I2C
Post by: amwales on August 06, 2014, 07:38:08 am
SuzyC, the code snippet I sent you should be easily translatable and I had only a little trouble getting it to work. You should give it a try, simply take the isr code, port it to xc8 or which ever compiler you are using. If you decide to run the i2c code outside the isr make sure the code is not interrupted since I found some devices do not properly honour clock stretching ( raspberry pi ) and you have to get the i2c code processing as fast as it can.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 06, 2014, 08:49:01 am
Thanks again 22swg,

I am not using the WDT, and the waveforms always look free of noise/spikes on a 200MHz scope. Breadboarded or not, the waveforms look very good to me!

I would be surprised if it is a WCOL because there is only one master clocking everything and the Master checks the clock line in it's send routine to Slave for a high level before it starts to make any transmission.

In any case, I have used error detecting bytes in the transmission-reception, so if there is a problem detected, the data is discarded and it is a case of try again.

After all I have got very good scores now, 25000 or more successful TxRX without any TX Rx failures, even if I have settled to accept things going on at a slower clock rate than I anticipated.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 06, 2014, 09:11:41 am
The real problem nows:
How to get information Tx-RX'd without having the peeking at bytes on the Slave while the Slave might be updating the same bytes I want to be sent to me without resorting to turning off the IRQ's every time a var is being changed rapidly during some task on the Slave. If I turn off the IRQ's before any change in byte value I will have my code overflowing with the turn on/turn off of IRQ's. Probably enough of them to run out of memory and seriously upset the clock/timers on the Slave.

On the other hand, I can save all the vars I am interested in in a cache array and have a flag byte tell me that the cache has been updated or is being updated.
 
(1) I send a request to Slave to Update Buffer Cache Array(has all the values)
     A update flag var is set on Slave in the IRQ,  RTS=Request To Send.
(2) The list of vars is updated when RTS detected in passing along the main() loop.
(3) A routine updates all the Vars and sets flag RTS=Ready To Send.
(4) I sent a request to Slave for the RTS byte.
(5) If the RTS is Ready to Send I send a SendBytes Command to Slave and grab the bytes in the Buffer, one IRQ for each byte number, or maybe get two or more bytes at a time being careful to not be running out of ISR time.
 
This results in data slightly stale, might take a few mSecs, but that's fast enough for me.

Am I good to go with this? 

(3) I send Slave a command byte requesting the cache status RTS flag byte.
Title: Re: Help Me Continue My I2C
Post by: senso on August 07, 2014, 01:51:49 am
There are lots of 5v 16bits pics, for example dspic3011, 40 pins, 10 pwm, 5 16 bits timers 2 32 bits timers, all in a dip package, come on, use the search/pic selector and find a better one..
Title: Re: Help Me Continue My I2C
Post by: bobcat on August 11, 2014, 03:40:41 pm
On long I2C lines > 2"", termination is important. I have good luck using 4.7K pull up resistors to Vcc. Also add a 470 ohm resistor in series with both of the clock and data lines. Place the series resistors close to the MPU. Even "clean" looking signals on a scope can be bad.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 21, 2014, 01:05:40 am
Thanks Senso, I didn't realize there were DIP packaged dspic.  I have taken a look at these chips, they might be the ticket..
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 21, 2014, 01:34:14 am
Thanks again 22swg, for your valuable advice to pay attention to WCOL issues

I thought I was getting  good transfers from master<--->slave, but it was an illusion. Once I added to the slave WCOL=0 SSPOV=0 before the start of the slave i2c ISR code, the transfer from master to slave seemed without error, that is, master-->slave worked fine half of the time; but transfers failed right after the SEN command every other time it was attempted by the master. It seems that the master, after sending a command, and terminating the transmission with PEN=1, would trigger a failed start of the next transfer, at the very start of the very next transmission. Then, once the code was repeated again, it worked ok.

Once I added WCOL=0;' SSPOV=0; at the very beginning of my sub-routine code that sends a command to the slave right before the SEN=1  then my master<--->slave code worked perfect!

Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 21, 2014, 01:38:19 am
Thanks to Bobcat!

I still do not understand why the i2c baud rate is still limited to approx to a  period of 6uS minimum in order to get error free transfers. The freq. of the i2c clock is less than 200KHz, but I can't seem to get it to run any faster even if I am just master--> slave only operation. I have tried again higher values of pull-up resistors(5k) but it only works worse.

The 16F88x spec sheet alludes to 1MHz baud but only shows specs for 400KHz and 100KHz operation. I can't do better than <200 KHz. I have yet to try 470ohm resistors in series with the ic2 Tx Rx pins.

However, I can still send a 5-byte command sequence to the Slave and get back 26 data bytes from a Slave's sensors all within 3mSec per MMMMM.

And that's good enough for me at this time to get this robot dancing!

Maybe it's my code.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 21, 2014, 01:48:34 am
Sorry to have taken sooooh long to reply to some of the people who generously took time out of their busy day to share their advice and deas with me!

Thanks a million to all you guys!


What really made my code make a turn to working was changing my code to use the i2c status register to create a state machine. It really made the difference in getting my code' to work when I knew how to respond codewise when a Start Sequence or R/*W or Data/Address was the last event in i2c land. Before that I was just looking at SSPIF and not paying any attention to these these important flags that tell the state of things i2c-wise. On top of that I was also ignoring WCOL and SSPOV's that were shouting at me!

I have been so thrilled to get my four MMMMM's to control each motor to go fast and slow, forward and reverse that I started to play with my prototype's construction and control code and sensor code and it took me just to recently to look back to the basics of having a perfectly reliable i2c and I have to say, I am so glad to see it work as well at is does!

What does it matter so much at this point if sometimes each MMMMM is a little bit of a jerk? :-DD
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 21, 2014, 02:00:09 am
Oh Dear!

Amwales, you too gave me a clue about WCOL that helped me to solve the i2c problems.

My thanks!
Title: Re: Help Me Continue My I2C
Post by: amwales on August 26, 2014, 08:04:20 am
Glad you got it working, what speed did you finally manage to achieve?
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 26, 2014, 03:18:46 pm
Amwales, Thanks Again for y our help:

As I have said a little earlier on this post page, the latest news is I canl send a 5-byte command sequence to the Slave and get back 34 data bytes from a Slave's sensors all within almost exactly 3mSec per MMMMM, though the time bounces around a bit by winning or losing the ISR time lottery.

So the clock period is very close to 6uSec, a speed <200KHz, and any speed faster than that gives me errors break dancing all over my i2d score card and I donno why!
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 26, 2014, 03:27:41 pm
Whaz is a real problem is PWM using a single powerful MCU. Some posters suggest I should stick with just one big MCU chip.

But when  I use a single chip each to control each of the four motors, then each or all four PWM's ON period starts at the same time, so the battery faces a huge surge load. This is why I think my MMMMM approach is going to work better, because each PWM is driving their motor asynchronously with their MMMMM peers, PWM-wise. 

The other issue is with an 8-bit MCU, such as the ATMEGA 2560 or the presently being used 16F886's,is that I cannot get my
code to do more than a few floating point calculations before i have used up all the program memory and the available MIPS.

Maybe I need to start a new post:  Which processor is the easiest to graduate to from an 8-bit to start doing some highly educated management of my MMMMM's????
Title: Re: Help Me Continue My I2C
Post by: dannyf on August 26, 2014, 07:13:55 pm
I think you made your life unnecessarily difficult.

Even though a slave is difficult to code, it is not impossible to code, even for a newbie. SPI slaves for example are quite simple. So is an uart receiver.

If I were you, I would have done either a spi slave (which needs two lines for the bus, and 4 lines for chip select);

or better yet, a uart receiver - 1 line for each chip, or with some additional coding, 1 line for all chips (as many as you want) if you allow a protocol there. Such a system has the added advantage of being very scalable.
Title: Re: Help Me Continue My I2C
Post by: nctnico on August 27, 2014, 12:32:09 am
From a functional point of view I2C is the easiest to make a master/slave system because the hardware also does the address decoding. With SPI, UART, etc you'll always have to do the addressing in software.
Title: Re: Help Me Continue My I2C
Post by: SuzyC on August 27, 2014, 08:53:57 pm
Thanks again nctnico,

I have been busy on my new post and just now had a few mins to take a look at this one.

I have not tried using the UART because I found the baud rate setting tables a little more than confusing and the problem of addressing four separate seemed rather difficult in terms of software and at the same time some other slave was having a conversation, every other slave would have an interrupt and somehow resolve if it was the target of the master's attention.
On the other hand, the problem of using the UART becomes simpler if some pins are allocated to chip select/direction control, but I have just about run out of pins on the master,due to a LCD display, a momentary switch, 6 A2D's and a rotary encoder, and one of two bits for hardware flags/debug purposes,  though I have quite a few of the 28-pins left over on the slaves.