Using an I2C / SPI LCD on the Spark Core

Hi @NanoAkron

I think the shifting of i2c addresses was fixed a long time back now.

The really important thing is that your have pullup resistors on both i2c lines. Arduino typically doesn’t need these but Spark always does!

I looked for the library for that display but I did not find that exact one in the library–just a dead-ish link to a Wordpress site. If you post the library or point us to it, we can figure out if it needs work.

@NanoAkron, the I2C address issue WAS fixed a long time ago as @bko alluded. I’ve ported a number of display libraries and would be more than glad to port your library as soon as you point me to it :smile:

1 Like

@peekay123 Thank you very much for your offer - it would be a great help.

I found the versions which work on the Arduino through http://playground.arduino.cc/Code/LCD

About halfway down there’s a section for ST7036 LCD driver/controller. This links to:

https://bitbucket.org/fmalpartida/st7036-display-driver/src

All the source should be there. As I said, it works straight off on the Arduino. I’ve edited out all the parts in the demo which look for the chip temperature and have reduced it to:

#include "ST7036.h"
#include "application.h"
//#include "lcd.h"

ST7036 lcd = ST7036 ( 2, 20, 0x78 ); //2 lines, 20 characters, 0x78 address

void setup ()
{
   lcd.init ();
}

void loop ()
{
  lcd.clear ();
  lcd.setCursor ( 0, 0 );
  lcd.print ("Temperature:");
  while(1)
  {
      //just do nothing
  }
}

Now…I’ve added 10K pull-ups as @bko recommended, but it’s still not working. Is this value too high? It works with the Arduino.

But I think this would be worth porting and adding to the library collection anyway - it’s a pretty nice LCD for anyone out there looking for one. Please let me know if you can see where I’ve gone wrong.

A value of 1k to 5k would be better, with 4.7k being ideal. That said, 10k probably works OK too.

@NanoAkron, I’ll have the library ready in a couple of hours :slight_smile:

UPDATE: The library is here. Please let me know if it works so I can publish it as a web IDE library. :smile:

1 Like

Thanks! I’ll get right on it.

I found the down-shift of the I2C address in ST7036.cpp’s constructors interesting - is this something you’ve seen in other libraries?

Oh, and you should add your own name as an addendum to the preamble in these files :smile:

Edit: Unfortunately it doesn’t seem to be working. It calls every part of the program, just that nothing appears on the screen. I’ve added lcd.contrast(10) to the setup as well.

Further edit - reading the data sheet for the ST7036 chip at:

Page 54 says that with a 2.7-4.5V supply (I’m using the Spark’s 3.3V supply), the I2C clock frequency should be less than 300kHz.

Is there any way to lower the I2C clock frequency from the Spark, or is it always set to 400kHz?

@NanoAkron, the I2C clock is 100Khz on the Spark
. Do you have pull-up resistors on the I2C lines?

Hmm…yes - 10k on each. I have an oscilloscope at work, but unfortunately there’s only a WPA Enterprise connection, meaning I can’t even get the program to start running.

Let me check the display again with my Arduino this Monday and get back to you.

Cheers!

@NanoAkron, if you add these lines at the top of your code, it will start the Spark without wifi and cloud connections so you code will run immediately:

#include "spark_disable_wlan.h"
#include "spark_disable_cloud.h"

You may want to try 4.7K pull-ups. I will review the code some more to see if I missed anything. :smile:

1 Like

I’ll try out what you’re recommending on Monday. Can I ask how I re-flash if I’ve disabled WiFi and cloud connectivity?

@NanoAkron, the short answer is via USB using dfu-utils and the Spark CLI comes in hand as well. There is another trick, however, that I used at the Maker Fair since the wifi there was bad at best! I define a pin on the Spark as a “WiFi enable” pin and check it in setup(). The Core starts with wifi and cloud off and if the pin is grounded, I turn them both ON:

#include "spark_disable_wlan.h"
#include "spark_disable_cloud.h"

//...

#define WIFI_JUMPER	D0    //Can be any pin

void setup()
{
	pinMode(WIFI_JUMPER, INPUT_PULLUP);
	if (digitalRead(WIFI_JUMPER) == HIGH) {
		WiFi.on();
		while (WiFi.status() != WIFI_ON)	//Wait for wifi to come ON
			SPARK_WLAN_Loop();
			
		Spark.connect();
		while (!Spark.connected())
			SPARK_WLAN_Loop();
	}

	//... rest of your code
}

So if you power up/reset your Core with the pin OPEN, it will enable wifi. With the pin shorted to ground, wifi will remain OFF and your code will run as usual. :smile:

@NanoAkron, I agree the address shift part is weird. Try removing the “>> 1” on each instance to see if that helps. I could not find any explanation in the module documentation and in fact, their examples seems to suggest otherwise (no shifting). I will remove it in my github code as well. :smile:

@peekay123 That pin grounding trick looks like an EXCELLENT work-around until the firmware gets tweaked a little more. You should really make it a top-level sticky!

I’ll try your other recommendation as well. Thanks!

@peekay123 I’ve been doing some skimming of the Arduino’s and Spark’s I2C/TWI code and there’s quite a difference in just the amount of code for each system. The Spark seems to have quite a bare-bones implementation - is there possibly some important functionality missing from the Spark’s code?

Arduino:
https://github.com/arduino/Arduino/blob/master/libraries/Wire/Wire.cpp

which calls further functions from:

https://github.com/arduino/Arduino/blob/master/libraries/Wire/utility/twi.c

And here’s ST Microelectronics’ own I2C code for their STM32f10x series:

https://code.google.com/p/stm32-codes/source/browse/trunk/StupidFish/Stm32FWLib/src/stm32f10x_i2c.c?r=19

Certainly seems more comprehensive than the Spark’s I2C code.

All of that code is in

core-common-lib/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c

and called by the spark_wiring_i2c.cpp user-level code.

@NanoAkron, @timb is about to release a totally overhauled version of the I2C library for the Core which will also support DMA and 400KHz clocking. :smiley:

@bko :frowning: I think I’m grasping at straws here.

@peekay123 That sounds great. Maybe I’ll just hold off for a bit.

1 Like

@peekay123 IT WORKS!!!

I’m so sorry about this, and I feel like a total idiot - I plugged that LCD back into my Arduino at work and it was dead. The backlight was fine, but the onboard chip itself must have been killed sometime over the weekend.

So, I tried it with another screen I have and SUCCESS!

I’ve kept the down-shift of the address as seen in the original library, but have added a couple of lines for future functionality (large fonts which occupy both rows at once):

Under the ‘LCD command set’, I’ve added:

const uint8_t DOUBLE_HEIGHT0 = 0x34; // Function set - 8 bit, 1 line display 5x16, inst table 0 const uint8_t DOUBLE_HEIGHT1 = 0x35; // Function set - 8 bit, 1 line display 5x16, inst table 1 const uint8_t DOUBLE_HEIGHT2 = 0x37; // Function set - 8 bit, 1 line display 5x16, inst table 2

and am now working out how to create a function .printLarge to take advantage of this.

Thank you so much for your help over the weekend - it was all down to hardware in the end.

2 Likes