Making I2C work on PIC18 - embedded

I'm using PIC18F87J11 as the master and LiPower Shield as the slave, and all I want to do is to be able to read the battery voltage value from the LiPower Shield. I'm using MPLAB C18 libraries for the I2C communication. I'm not able to get correct readings as I think the communication between the two devices is not setup correctly.
I'm looking for interpretations of the waveform signals in order to detect the issue. Also I would like to know if I'm missing something in the code. Any recommendations to improve the code would be helpful.
The LiPower Shield came with a sample code for Arduino but I'm using PIC18 chip from Microchip. The sample code is found here.
Here is the signals I'm getting while trying to read the battery voltage.
Code:
SSP2ADD = 19;
OpenI2C2(MASTER,SLEW_OFF);
StartI2C2();
IdleI2C2();
WriteI2C2(0x36);
IdleI2C2();
data = ReadI2C2(); // Read byte of data
printf ("\r\nAddress 32");
printf (" Byte:");
PrintChar(data);
IdleI2C2();
AckI2C2();
IdleI2C2();
WriteI2C2(0x02);
IdleI2C2();
data = ReadI2C2(); // Read byte of data
printf ("\r\nAddress 02");
printf (" Byte:");
PrintChar(data);
IdleI2C2();
AckI2C2();
StopI2C2(); // Stop condition I2C on bus
Output: Which I think is wrong.
Address 32 Byte:FF
Address 02 Byte:FF
I'm not really sure if I'm writing/reading from the correct address, but that's the address they used in the their sample code. I hope I can get some interpretations on the signals and feedback on the code if possible.

I'm not familiar with the PIC but your code looks nowhere near right. Per the MAX17043DS datasheet, page 12, a memory read must consist of the following:
I2C start condition
Write device I2C write address (0x6C)
Check for ACK from slave
Write 8-bit memory address
Check for ACK from slave
I2C repeated start condition
Write device I2C read address (0x6D)
Read first byte of data
Send ACK
Read second byte of data
Send NACK
I2C Stop condition
What I see in your code is an I2C Start condition followed by a write 0f 0x36. Since this is not the device address the slave recognizes, it sends a NACK (as seen on your logic analyzer traces) and ignores everything else.
This question and answer has a lot of information on I2C on a PIC18. You also should probably find a read a basic I2C tutorial.

Related

XBee S1 read values from API mode

I have two XBees S1-one attached to a temperature sensor. This Xbee reads analog values, converts them into digital values thanks to the ADC and transmits them.
The other XBee - the receiver, is connected to a computer via a USB Explorer.
This XBee works in API mode. The XBee connected to a computer receives the data send by the transmitter. I monitor the received values with the X-CTU software, version 6.2.0. Up until this point, everything works fine.
However, the problem that I encounter is that the data received on the computer is coded: there are bits corresponding to the address of the receiver, bits corresponding to the address of the sender, the data itself, acknowledgment bits,etc. My question is how can I extract only the data bits without all th other information send by the transmitter?
I tried to read the values with a USB to TTL cable, connecting this cable to the Tx, Rx,GND and 5V(there is a 5V input in the USB Explorer despite that the XBee works at 3.3V) of the receiver XBee and using the screen command in Linux. However, in this way I receive ASCII characters and I want to receive the binary code.
I want to put those values in a database in order to be able to treat them later.
Thank you for your assistance.
With a library like this one, you can use function to get the data from your Xbee in python ;) (if you use linux)
You just have to initialise the port (should be on /dev/tty...) and than catch the data with a loop which check if new data is coming.
If you need more help I can send you part of my code (doesn't have it near me, it's on my raspy)
I hope I've help you ;)
Thana

i2c analysis on oscilloscope

I am using a cortex m3 based mc.
I scoped my communication with a logic analyzer, but I don't really understand what I see. Can you help me?
I am using 10k pull up resistors
I am trying to send the data: 0x55 . I (think) don 't see the data, only an -address
On the following pictures you can see the address, but I think it s not correct or am I mistaking.
There is no sensor wired to the mc yet, I changed the address to analyze.
adress 0x00, data 0x55 : http://imgur.com/OJfe8Dj,7REdHS7,PLz1qTZ
address 0x55, data 0x55: http://imgur.com/OJfe8Dj,7REdHS7,PLz1qTZ#1
address 0xff, data 0x55: http://imgur.com/OJfe8Dj,7REdHS7,PLz1qTZ#2
My code:
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C7);
GPIOPinConfigure(0x00001002);
GPIOPinConfigure(0x00001402);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_5);
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_4);
I2CMasterInitExpClk( I2C7Master_Base, SysCtlClockGet(), false);
I2CMasterSlaveAddrSet(I2C7Master_Base, 0xff, false);
I2CMasterDataPut(I2C7Master_Base, 0x55);
I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_SEND);
while(I2CMasterBusy(I2C7Master_Base));
Can somebody give an explanation?
Indeed you better make a wired connection between master and light sensor. Then you need to send a proper address of the sensor which should be acknowledged by slave. You will see ACK-bit in the scope when the slave acknowledges on its address. Next you are going to operate with data according to the datagrams on the sensor - any data byte should be also acknowledged (most likely, or kind of due to datasheet). Start with wired connection because there is no big sense to try I2C bus without load, we can't even see 8-9 clock cycles on the diagram you posted because it is without load connection I think. Hope it helps.

MSP430 SPI to M25P64

I have a SPI for MSP430 written. If I send WRSR(01h) or RDSR(05h) to M25P64 flash.
The response I get from the Flash SPI_MISO is FFh.
So my question is "Is the response I have obtained is it right?"
How do I come to an understanding that handshaking between my SPI and Flash is correct?
Thanks
AK
Is the response I have obtained is it right?
The response is wrong. 30 seconds on Google and in the datasheet will tell you that. Things to check (since you have not provided any information):
How do I come to an understanding that handshaking between my SPI and Flash is correct?
Is this a new piece of SPI code? If so have you checked with an oscilloscope to see what you send out (clock and MOSI) is what you expect and matches what the datasheet says the device expects? It's the definitive way to be sure.
Does your SPI code work with any other devices?
Are your IO pins configured correctly on the MSP430?
Have you got the SPI module configured correctly for phase and polarity?
Did you forget to assert the chip select line?
What about HOLD?
Did you remember to send a dummy byte after the RDSR command so that the device would send the status register value?
Do you see a response from the device on an oscilloscope? Does the MSP430 read that value or a different one?
You are sometimes better first of all trying to read the device ID rather than the status register for a new piece of code. The reason for that is the device ID will never change, whereas the status register might change (although that depends on the device).

PIC I2C slave ack on data

I am looking into the I2C protocol for PIC16F88X.
What I would like to do, is to enable an I2C slave to either ACK or NACK depending on the data received on the I2C.
The PIC can ACK or NACK on the I2C address sent on the line, but from what I've read it will always ACK on the subsequent received bytes. Is that correct?
In the following communication:
Start - I2c_Addr+write/ACK - Register_value/Nack
I'd like the slave to be able to Ack or Nack depending on the value in Register_value. If the slave does not understand Register_value, it should not Ack.
Could someone please either confirm that this is not possible, or tell me how to do it?
Assuming your using the MSSP peripheral
short answer: What your asking for is not probably possible with a PIC, at least without bit banging I/O lines. The reason is that ack / nack is checked on the 9th clock edge and the SSPIF interrupt is not fired until the end of the 9th clock. You could attempt to repeatedly check the BF bit as it is set as soon as the data byte is shifted into the I/O register(8th clock). If you can pull off a comparison and set the SSPOV bit before the 9th clock cycle this should generate a NACK, this is quite sketchy if you have any interrupts running.
longer answer: it sounds like your attempting to validate if the data byte the slave receives is valid or not using ack. personally i wouldn't do this, ack is to signal the integrity of the line, not verify data integrity. If the device is a slave the master by definition must know exactly how it is to work and can check the validity of the byte before pushing it out on the I2C lines. In such cases i assume you also have control over the I2C master's code, use one common header file that defines all the commands or valid data bytes that can be sent to avoid mismatches in the code.
If you must guarantee the proper byte was sent for some reason, have the master ask the slave for a response byte, have the slave return a code indicating the result of the previous transfer.
If your intent is to guarantee the integrity of the I2C line, none of these approaches really work. Your only option would be to send a bulk of a bytes at boot or periodically with a CRC and check that it matches on the slave. Generally I2C lines will either work or not, they are low speed, generally have short traces and have high allowable bus capacitance, if they arn't working you won't see any ack's at all.
My guess is no IF the I2C hardware is built-in to the PIC. All of the hardware solutions I've worked with have a state machine that can't help but ACK the second byte unless there's something wrong with the transmission (missing a bit for instance). You'd be better off making your own I2C implementation in software with bit-banging and an open-collector buffer for the ACK. Then you can do anything you want. It won't be I2C standard, so watch out if you put any devices on the bus that aren't working to your specifications. I'm not sure offhand but I think for any standard I2C device if it doesn't receive an ACK it may retransmit the data or just fault since it isn't sure who has control of the bus after a failure (signified by a NAK).

Getting Epson receipt printer to print from Arduino

I'm trying to build a microprinter using an Arduino and an Epson TM-T88II receipt/POS printer. The printer uses the Epson Esc/POS system, but I can't get it to do anything at all from the Arduino. I'm doing things like:
#include <SoftwareSerial.h>
#define out_pin 3
#define in_pin 2
SoftwareSerial printer = SoftwareSerial(in_pin, out_pin);
void setup()
{
pinMode(in_pin, INPUT);
pinMode(out_pin, OUTPUT);
printer.begin(9600);
delay(1000);
printer.print(0x1B, BYTE);
printer.print('#'); // ESC(HEX 1B) # is supposed to initialize the printer
printer.print("hello world");
printer.print(0xA, BYTE); // print buffer and line feed
}
I just can't get the printer to respond at all. The printer powers up and prints its self test just fine. It's a serial (RS-232) printer, and I'm connecting it to the Arduino through a MAX233 chip. I've checked and rechecked my connections through the chip, which I think are right based on a friend who has a similar setup working. I read somewhere that the TM-T88 printers need null-modem serial cables, so I bought an adapter, and that didn't seem to make any difference.
I'm new to electronics, so I'm completely stumped. I just want to get it to print something, so I can get to the fun part - the programming :). Any thoughts on things to test/try? I can give more detail on wiring or anything else, just didn't want this to get TOO long.
Are you using an RS-232 transceiver? The Arduino outputs 0 and 5 V for serial, while the printer uses -12 and 12 V for serial. You should use a MAX232 or similar device to get the correct physical interface. (You might be able to cheat if you invert the serial port on the Arduino, but that might not work, and it's more trouble when just getting started.)
Once that's taken care of, the RTS and DTR may be your problem. You should be able to change the DIP-switch settings on the printer and turn off flow control altogether, or switch it to software flow control.
Also, you may need to send both line feed and carriage return.
However, once all that's done it should print just fine, even without any reset commands. Send a bunch of ASCII characters and line feed/carriage returns, and it'll spit it all out.
You can ignore the RX line (on the Arduino side, TX on the printer side) for now - just send it data until you figure out the wiring, level conversion, flow control, etc.
You could check whether you can communicate with a PC, both from the Arduino and to the printer.
I would use an oscilloscope to see if the serial signals come out of the Arduino and the MAX as they should, but then you probably don't have one.
Are you sure the communication settings are correct? You set the baud rate to 9600, but what about data bits, parity, stop bits? What about the control lines?
I'd hook another PC instead of the printer to the other end of the serial cable and run telnet or PuTTY on that system to make sure you are communicating out and actually talking through the serial port. If so, you could use the same solution to send data to the printer to confirm all settings such as number of data bits, parity, etc.
I've done a similar project and had the same issue. You need a null modem / crossover cable to go from max232 to the printer as both devices are in slave configuration