• 0
Blessing

interfacing PmodCLS with an arduino

Question

how I can use PmodCLS with an arduino uno communicating through ic2, see snippet below for picture of the PmodCLS that I am referring to 

 

 

Share this post


Link to post
Share on other sites

6 answers to this question

Recommended Posts

  • 0

Hi Blessing,

I'm not seeing the picture of your setup that you mentioned, but I presume you are referring to this PmodCLS? If so, the first thing that I would want to do is confirm that my jumper settings on the PmodCLS are correct and that I am connecting the correct pins from the microcontroller to the PmodCLS based on the Communication Protocol Selection section and the Pinout Description section, respectively, of the PmodCLS reference manual.

Since you are wishing to use I2C, and taking a look at the Arduino Uno schematics, you will need to implement pull-up resistors on both the SDA and SCL lines so that you can communicate through I2C successfully.

The tricky bit here will be that Digilent currently only has library support for the PmodCLS through the SPI protocol using the Digilent SPI library. Unless you're already familiar with the I2C protocol and the Wire library that Arduino supports so that you are able to change the library from using SPI to I2C, it may behoove you to instead use SPI to communicate with the PmodCLS for your final project.

Let me know if you have any more questions.

Thanks,
JColvin

Share this post


Link to post
Share on other sites
  • 0

I have been working with the PmodCLS and have completed designs for all three serial interfaces/  I used the mpide code downloaded from https://reference.digilentinc.com/_media/reference/pmod/pmodcls/pmodcls-mpide-lib.zip. The function to clear the display and home the cursor shown below appears to have an error. According to the Instruction set found at https://reference.digilentinc.com/pmod/pmod/cls/user_guide, the array should not contain the '0' character. The string should be: "uint8_t dispClr[] = {ESC, BRACKET, DISP_CLR_CMD};"   

void LCDS::DisplayClear() {
    uint8_t dispClr[] = {ESC, BRACKET, '0', DISP_CLR_CMD};
    //clear the display and returns the cursor home
    SendBytes(dispClr, 4);    // After changing the text string, the "4" in this line should be changed to "3"
}

Since the example code is only for the SPI interface, be sure that JP1 is in the "SS" position so the device select operates correctly.

I developed three test projects using the MPLAB X IDE (not Arduino). I used the same test code that displays a count that is incremented once a second for for all three serial interfaces.  I left the UART and I2C test programs run over night resulting in over 30000 seconds. When I run the SPI interface, the LCD goes blank after 107 seconds even though the PIC32 continues to send SPI data.  This failure is independent on what else is being displayed.  This is a curious failure mode.  

I am wondering if anyone else has encountered this problem.  I can supply my test projects upon request but the code is written for a PIC32MX370 processor which is a PPS device.

 

 

Share this post


Link to post
Share on other sites
  • 0

I believe I found the issue with the PmodLCS and the SPI interface..  I was using a 1 second time delay function that reads the core timer using the code in Listing 1. After 107 seconds, this polling delay would suddenly cut short my delays thus blasting an number of LCD SPI packets in a very short interval. Even though the delay function would eventually recover, the LCD operation was compromised causing the LCD to go blank. 

It is no coincident that the maximum delay using the delay code in Listing 2 below is 107.374 seconds. (2^32/40,000,000 = 107.374).  But this limitation does not explain the failure of Listing 1 since I was only delaying 1000 ms or 40,000,000 core timer ticks. I believe that the problem lies in my understanding of how the XC32 compiler implements the unsigned magnitude compare embedded in the while statement.

Listing 1.  Bad polling delay function

void DelayMs(unsigned int mS)
{

// CORE_MS_TICK_RATE = core timer frequency / 1000 or 40,000,000/1000
unsigned int tWait;
    tWait = (CORE_MS_TICK_RATE * mS) + ReadCoreTimer();
    while(ReadCoreTimer() < tWait); /* wait for the time to pass */
} /* End of DelayMs */

Listing 2.  Good polling delay function - 107 seconds maximum

void DelayMs(unsigned int mS)
{
// CORE_MS_TICK_RATE = core timer frequency / 1000 or 40,000,000/1000
unsigned int tWait, tStart;
    tStart = ReadCoreTimer();
    tWait = (CORE_MS_TICK_RATE * mS);
    while((ReadCoreTimer()- tStart) < tWait); /* wait for the time to pass */
} /* End of DelayMs */

 

Share this post


Link to post
Share on other sites
  • 0

Hi Flyline,

Thanks for the catch on the DisplayClear command! I have updated the library available on the PmodCLS Resource Center with the corrected code. I'm not sure why the '0' was in there, but I suspect it was a leftover artifact from some of the other functions where users need to specify a particular location for the action to occur. 

I am not certain I fully understand the difference between the two listings though. I can see that Listing 1 ends up putting tWait at a greater value than the
CORE_MS_TICK_RATE * mS by adding the current core timer value, but I would think the while loop then intrinsically accounts for that mathematically since from my understanding Listing 2 accounts for the initial core timer reading on the left-hand-side of the '<' as tStart, rather than including it on the right-hand-side within tWait.

Thanks,
JColvin

Share this post


Link to post
Share on other sites
  • 0

Dr. Jim Frenzel at the University of Idaho figured it out for me last night. His explanation goes like this:

Say tStart = FFFFFFFC and (CORE_MS_TICK * mS) = 00000006

 

so, in the incorrect implementation: tWait = 00000006 + FFFFFFFC = 00000002

 

Then, if you were to immediately compare the CoreTimer to tWait as unsigned numbers the CoreTimer will look larger, even though no time has elapsed. 

That’s why it is critical that you first subtract tStart from the current value of the CoreTimer, then do the comparison.

Applying the above scenario to the correct version

tStart = FFFFFFFC.  (which happens to be -4 in two’s complement) and tWait  = 00000006

 

Then (CoreTimer – tStart) = 0, and the next tick it will equal 1, and it increments until it reaches 6 and the while loop. is exited.

As I expected - the error was my interpretation of how 2's complement math works for unsigned numbers.

Share this post


Link to post
Share on other sites
  • 0

Hi Flyline,

That makes sense. I was wondering if it would be due to a rollover problem, but I imagined that rollover problems would be present in both situations so I didn't run look into how the math might work. Thanks for the explanation!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now