The TSL2561 is a chipset capable to read IR and visible light intensity and is the chipset used in the iRis project.
This article give some suggestions about how to use this sensor.
Translate
Showing posts with label i2c. Show all posts
Showing posts with label i2c. Show all posts
Saturday, May 19, 2018
Saturday, November 14, 2015
Timer for UV box
Ok, here the deal.
The need is to develop a timer, faster, capable to control up to 16 UV fluorescent bulbs.
Up to 2 hours, 1 second precision, display to show the countdown and menu' management, digital encoder for input, pushbuttons/LEDs.
It can be done in thousands ways, but this time I'll try to put it together using Energia and a BIG help from Roberto.
The need is to develop a timer, faster, capable to control up to 16 UV fluorescent bulbs.
Up to 2 hours, 1 second precision, display to show the countdown and menu' management, digital encoder for input, pushbuttons/LEDs.
It can be done in thousands ways, but this time I'll try to put it together using Energia and a BIG help from Roberto.
Friday, October 30, 2015
Working on the iRis project
[To be updated !]
A step-by-step guide to work on git for the iRis project.
If you are new on git and github, read this article first.
The iRis project is on github, so if somebody wants to join it, or just follow the progress, can clone the git repo for iRis.
A step-by-step guide to work on git for the iRis project.
If you are new on git and github, read this article first.
The iRis project is on github, so if somebody wants to join it, or just follow the progress, can clone the git repo for iRis.
Saturday, August 8, 2015
MSP430 - I2C library
There are many different library out there to handle I2C with the MSP430.
Some of the libraries are also "official", from TI.
I found a nice and simple C library to handle the I2C with USI is on github and apparently is easy to deploy and use.
This article contains some notes about how to deploy and use the library, closing some missing practical information.
Let's start with ... the hardware.
The library was originally developed and tested on an MSP430g2452.
It surely can work on any MSP430 family member that has a USI, that's was anyway my initial intent.
I tried to use an MSP430f2013 but in the end I opted to buy some MSP430g2452 because the 2013 doesn't have enough memory (only 2K ROM) to handle protocol and the rest of the code needed for a project.
The MSP430g2452 has 8K ROM.
After choosing the microcontroller, the attention was concentrated on the I/O pin to use.
Note ! Initially I'm experiment using a Launchpad.
The library expects to use the USI pins, i.e. the P1.6 for the SCL and the P1.7 for the SDA.
Apparently there is NO need to bother with the I/O ports to inform the MSP430 that the 2 pins are dedicated to the USI in I2C mode.
Is enough to program the USI control register to do that, and that is taken care in the i2c_init function provided by the library.
Important !!! The P1.6 on the Launchpad is connected to the green LED !
Remove the jumper on that LED in order to have something working !
The library presumably is written for IAR or other commercial system.
In order to compile it with Mspgcc few modifications are necessary.
I also fixed a bug that was preventing the library to read more than 8 bit at a time.
In the usi_i2c.c file, in the interrupt function Usi_txrx change the highlighted line :
..................................................................
..................................................................
case I2C_RECEIVED_DATA: // received data, send ACK/NACK
*i2c_receive_buffer = USISRL;
i2c_receive_buffer++;
USICTL0 |= USIOE; // SDA = output
if(i2c_sequence_length > 1) {
// If this is not the last byte
USISRL = 0x00; // ACK
..................................................................
..................................................................
The library has only three "public" functions and act as Master.
Let see how to use it.
The first public function is called i2c_init and like the name imply, is used to initialize the USI and set up the MSP430 to use it.
It must be called once, preferably after other basic I/O initializations happens.
After that, the "system" should be able to send out I2C messages.
Example:
i2c_init(USIDIV_5, USISSEL_2);
The first parameter determine the division applied to the input clock.
USIDEV_0 divide by 1, USIDEV_1 divide by 2, USIDEV_2 divide by 4 and so on (see MSP430 Family user guide - USICKCTL register).
The second parameter determine the source of the clock (see MSP430 Family user guide - USICKCTL register).
In the example above the source for the clock is the SMCLK divided by 32.
This function returns TRUE (1) or FALSE (0) to indicate if a transaction is running.
The I2C messages are sent via interrupt so it is possible that the main program is ready to send another sequence when the system is still handling the previous sequence.
So before to perform any request, better to see if the system is ready to accept it.
Example:
if(i2c_done())
i2c_send_sequence((uint16_t *)seq1, 2, (uint8_t *)recseq, 0);
or
while(!i2c_done());
Strongly suggested to use it to prevent to start a sequence when another one is still running.
Simply put, this function can send and receive information via I2C using a "sequence".
The sequence is a series of word and commands.
i2c_usi.h defines two commands :
The sequences to send depends strictly to a specific component so there is no a generic suggestion if not to carefully read the datasheet of the component.
Some of the libraries are also "official", from TI.
I found a nice and simple C library to handle the I2C with USI is on github and apparently is easy to deploy and use.
This article contains some notes about how to deploy and use the library, closing some missing practical information.
Let's start with ... the hardware.
Hardware
The library was originally developed and tested on an MSP430g2452.
It surely can work on any MSP430 family member that has a USI, that's was anyway my initial intent.
I tried to use an MSP430f2013 but in the end I opted to buy some MSP430g2452 because the 2013 doesn't have enough memory (only 2K ROM) to handle protocol and the rest of the code needed for a project.
The MSP430g2452 has 8K ROM.
After choosing the microcontroller, the attention was concentrated on the I/O pin to use.
Note ! Initially I'm experiment using a Launchpad.
The library expects to use the USI pins, i.e. the P1.6 for the SCL and the P1.7 for the SDA.
Apparently there is NO need to bother with the I/O ports to inform the MSP430 that the 2 pins are dedicated to the USI in I2C mode.
Is enough to program the USI control register to do that, and that is taken care in the i2c_init function provided by the library.
Important !!! The P1.6 on the Launchpad is connected to the green LED !
Remove the jumper on that LED in order to have something working !
Software
Compile it
The library presumably is written for IAR or other commercial system.
In order to compile it with Mspgcc few modifications are necessary.
- Remove the specific include of the msp430g2452 header from usi_i2c.c
- Add the generic include of msp430 in the usi_i2c.h
- Remove the include of the stdint.h header from usi_i2c.c and move in the usi_i2c.h
- Change the interrupt declaration, from:
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX(void)
{
switch(__even_in_range(i2c_state,12))
to
__attribute__((__interrupt__(USI_VECTOR)))
void Usi_txrx (void){ switch(__even_in_range(i2c_state,12)) - Move the inline function i2c_done() from the header file (usi_i2c.h) into the module (usi_i2c.c) and leave a function prototype for that function in the usi_i2c.h header file
With these modifications I was able to compile the library using mspgcc.
I also fixed a bug that was preventing the library to read more than 8 bit at a time.
In the usi_i2c.c file, in the interrupt function Usi_txrx change the highlighted line :
..................................................................
..................................................................
case I2C_RECEIVED_DATA: // received data, send ACK/NACK
*i2c_receive_buffer = USISRL;
i2c_receive_buffer++;
USICTL0 |= USIOE; // SDA = output
if(i2c_sequence_length > 1) {
// If this is not the last byte
USISRL = 0x00; // ACK
..................................................................
..................................................................
with
..................................................................
..................................................................
case I2C_RECEIVED_DATA: // received data, send ACK/NACK
*i2c_receive_buffer = USISRL;
i2c_receive_buffer++;
USICTL0 |= USIOE; // SDA = output
if(i2c_sequence_length > 0) { // TheFwGuy MOD !!!
// If this is not the last byte
USISRL = 0x00; // ACK
..................................................................
..................................................................
..................................................................
case I2C_RECEIVED_DATA: // received data, send ACK/NACK
*i2c_receive_buffer = USISRL;
i2c_receive_buffer++;
USICTL0 |= USIOE; // SDA = output
if(i2c_sequence_length > 0) { // TheFwGuy MOD !!!
// If this is not the last byte
USISRL = 0x00; // ACK
..................................................................
..................................................................
Use it
The library has only three "public" functions and act as Master.
Let see how to use it.
i2c_init
The first public function is called i2c_init and like the name imply, is used to initialize the USI and set up the MSP430 to use it.
It must be called once, preferably after other basic I/O initializations happens.
After that, the "system" should be able to send out I2C messages.
Example:
i2c_init(USIDIV_5, USISSEL_2);
The first parameter determine the division applied to the input clock.
USIDEV_0 divide by 1, USIDEV_1 divide by 2, USIDEV_2 divide by 4 and so on (see MSP430 Family user guide - USICKCTL register).
The second parameter determine the source of the clock (see MSP430 Family user guide - USICKCTL register).
In the example above the source for the clock is the SMCLK divided by 32.
i2c_done
This function returns TRUE (1) or FALSE (0) to indicate if a transaction is running.
The I2C messages are sent via interrupt so it is possible that the main program is ready to send another sequence when the system is still handling the previous sequence.
So before to perform any request, better to see if the system is ready to accept it.
Example:
if(i2c_done())
i2c_send_sequence((uint16_t *)seq1, 2, (uint8_t *)recseq, 0);
or
while(!i2c_done());
Strongly suggested to use it to prevent to start a sequence when another one is still running.
i2c_send_sequence
This is the main function and the most complex to handle.Simply put, this function can send and receive information via I2C using a "sequence".
The sequence is a series of word and commands.
i2c_usi.h defines two commands :
- I2C_RESTART
- I2C_READ
The function has these inputs:
- sequence
sequence is a pointer to an array containing the I2C operation sequence that should be performed.
It can include any number of writes, restarts and reads.
The sequence is composed of uint16_t, not uint8_t elements.
This is because the need to support out-of-band signalling of I2C_RESTART and I2C_READ operations, while still passing through 8-bit data.
The sequence uses the Bus Pirate I2C convention.
The address must be prepared manually, adding the R/W bit.
The address is prepared shifting the 7-bit I2C address to the left and add the R/W bit (0 to write, 1 to read).
The examples above communicate with a device whose I2C address is 0x1c, which shifted left gives 0x38.
For reads we use 0x39, which is (0x1c<<1)|1.
So for example, to write at the address 0x39, the sequence would be:
- 0x39 << 1 = 0x72
And to read from the address 0x39:- (0x39 << 1) | 1 = 0x73
- sequence length
sequence_length is the number of sequence elements (not bytes).
Sequences of arbitrary (well, 32-bit) length are supported. - received data
received_data should point to a buffer that can hold as many bytes as there are I2C_READ operations in the sequence.
If there are no reads, 0 can be passed, as this parameter will not be used. - wake up sr bits
Used if you want to use the MSP430 in low power mode.
Building sequences
The sequences to send depends strictly to a specific component so there is no a generic suggestion if not to carefully read the datasheet of the component.
Wednesday, December 3, 2014
TeirmiLab - Raspberry Pi prototype
This article describes the building of a TeirmiLab prototype based on a Raspberry Pi B board.
The goal using a Raspberry Pi is to have a machine that can be expanded later.
Shopping list
- Raspberry Pi B or Raspberry Pi B+ or Raspberry Pi A+
- RGB 16x2 LED display
- DS1820 (specifically this one)
- MCP23017 I2C GPIO expander
- I2C RTC clock (optional)
The idea is to use a traditional LCD display instead a more sophisticate touch screen display.
Mainly the reasons :
Mainly the reasons :
- is not expensive
- doesn't require to develop a graphic interface for it
- allows to focus on the purpose - to show a temperature
- can be easily placed inside a protective container (no touch capabilities)
Hardware
Here a initial schematic for the TeirmiLab-Pi.
The RTC clock module is actually necessary only for the enhanced version, for the data-log feature, however it will be tested also on the base version.
The idea is to use as much as possible "ready to use" modules, like the RGB display, the GPIO I2C expander and so on, in order to use already made code (see the Software section).
The encoder will be connected directly to the Raspberry GPIO as well as the interrupt signal from the MCP23017 (optional for now), in order to be able to detect faster changes from the keyboard.
The internal pullup resistors for the encoder will be enabled.
![]() |
| First tests on a breadboard |
| The second prototype on perforated board |
| The second prototype on perforated board |
| The second prototype with the keyboard and RPOf cable connected |
A new version of the hardware will include a digital encoder to be used instead the keyboard (see below).
![]() |
| The prototype installed on a wooden platform for a more mechanical stability. A monochromatic LCD is used instead an RGB one |
![]() | |
|
A new interface board is under development.
GPIO Use
Here a table for the GPIO use :
| Raspberry GPIO | MCP GPIO | Direction | Description |
| GPA0 | Output | LCD | |
| GPA1 | Output | LCD | |
| GPA2 | Output | LCD | |
| GPA3 | Output | LCD | |
| GPA4 | Output | LCD | |
| GPA5 | Output | LCD | |
| GPA6 | Output | LCD | |
| GPA7 | Output | LCD | |
| GPB0 | Output | LCD | |
| GPB1 | |||
| GPB2 | |||
| GPB3 | |||
| GPB4 | Input | Keyboard 1 | |
| GPB5 | Input | Keyboard 2 | |
| GPB6 | Input | Keyboard 3 | |
| GPB7 | Input | Keyboard 4 | |
| GPIO4 | Input/Output | 1Wire protocol | |
| GPIO17 | Input | Shutdown input | |
| GPIO18 | Output | Shutdown feedback | |
| GPIO22 | Output | Buzzer | |
| GPIO23 | Input | Encoder A | |
| GPIO24 | Input | Encoder B | |
| GPIO25 | Input | Encoder switch |
Sensor
With the sensor used (DS18B20) the TeirmiLab has these basic characteristics:
- Range -55 to 125°C (-67°F to +257°F)
- ±0.5°C Accuracy from -10°C to +85°C
Keyboard
- a Mode button
Allows to select different modes, like "display temperature" or "Set alarm" or "Set offset" - two + and - buttons
Allows to increase or decrease a value, like the alarm temperature or the offset
Encoder
Instead of the keyboard, it is more easy to use a mechanical digital encoder with an embedded pushbutton for the selection.
The pushbutton acts as Mode button and rotating the encoder cause the values to change.
The video is showing the encoder operations
Power Supply
The instrument must be powered.
An USB wall wart, with at least 1 A, will be the power source for the Teirmilab.
A main switch will be necessary in order to correctly power up and power down the instrument (see RPOf project)
Container
All the electronic will be placed in a transparent plastic box.
This will allow to reduce the drilling to the minimum, basically for the main power switch and eventually for some push buttons if not other means are used.
The display will remain totally protected but visible behind the clear plastic.
Saturday, October 11, 2014
Raspberry Pi - connecting a traditional LCD display (Update)
Raspberry Pi is a powerful enough platform and it is possible to use many recent touchscreen with a nice graphic on it.
However often a traditional LCD is more useful, and surely is more cheap than a touchscreen solution.
Here one way to connect a traditional LCD and use it in projects, like the TeirmiLab one.
This article describes how to connect a traditional LCD but with RGB capabilities to the Raspberry Pi B.
We need :
There are many ways to control the hardware.
For now I found a ready-to-use Python library published by Adafruit that is working nicely.
Again, the important thing is that control an LCD is not a critical task, so a python script is Ok.
Maybe in future I'll explore the possibility to control it directly in C.
Here a quick step-by-step guide (see Adafruit tutorials for a more detailed and easy instructions) :
At this point everything should be installed in order to use the display.
Here a couple of tips and resolutions.
If you start from a fresh installation of Raspbian, especially a lite version, before to start to follow the instructions above, be sure to execute :
Be aware about the type of kit you are using.
On the examples area there are different examples depending the type of display in use.
To test the basic display, use : char_lcd_mcp.py
To test the kit with RGB display and pushbutton use : char_lcd_plate.py
However often a traditional LCD is more useful, and surely is more cheap than a touchscreen solution.
Here one way to connect a traditional LCD and use it in projects, like the TeirmiLab one.
This article describes how to connect a traditional LCD but with RGB capabilities to the Raspberry Pi B.
We need :
- Raspberry Pi B or Raspberry Pi B+
- RGB 16x2 LED display
- MCP23017 I2C GPIO expander
It is possible to hook a display without the need of the GPIO expander, however a normal LCD uses at least 6 signals. 9 if the LCD display is an RGB one like the one used for this project.
Considering that the Raspberry Pi B doesn't have many GPIO available and that usually the speed required to handle the display is not critical, using a chip like the MCP23017 make sense.
In this way it will be enough to "hook" the chip to the I2C bus, leaving all the Raspberry Pi GPIO free for other use.
Considering that the Raspberry Pi B doesn't have many GPIO available and that usually the speed required to handle the display is not critical, using a chip like the MCP23017 make sense.
In this way it will be enough to "hook" the chip to the I2C bus, leaving all the Raspberry Pi GPIO free for other use.
Let see a schematic.
Software
There are many ways to control the hardware.
For now I found a ready-to-use Python library published by Adafruit that is working nicely.
Again, the important thing is that control an LCD is not a critical task, so a python script is Ok.
Maybe in future I'll explore the possibility to control it directly in C.
Python
To use our display we need to install some code in our Raspberry.Here a quick step-by-step guide (see Adafruit tutorials for a more detailed and easy instructions) :
- sudo apt-get update
- sudo apt-get install build-essential python-dev python-smbus python-pip
- sudo apt-get install i2c-tools
- sudo pip install RPi.GPIO
- cd ~
- git clone https://github.com/adafruit/Adafruit_Python_CharLCD.git
- cd Adafruit_Python_CharLCD
- sudo python setup.py install
Before to be able to use it, we need to be sure a configuration file is correctly set-up.
Execute : sudo nano /etc/modules
and if the file exists, add these two lines in the end.
i2c-bcm2708
i2c-bcm2708
i2c-dev
Save the file then open another one in edit.
Execute : sudo nano /etc/modprobe.d/raspi-blacklist.conf
Execute : sudo nano /etc/modprobe.d/raspi-blacklist.conf
In this file comment out the two lines showed below, adding # at the beginning:
#blacklist spi-bcm2708
#blacklist i2c-bcm2708
Reboot Raspberry : sudo shutdown -r now
or : sudo reboot
At this point everything should be installed in order to use the display.
First is better to run an utility to see if the I2C GPIO expander is seen correctly.
sudo i2cdetect -y 1
The command should display a table and in the table should be present a 0x20 address.
pi@raspberrypi ~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi ~ $
If so, the chip is correctly seen by Raspberry.
pi@raspberrypi ~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi ~ $
If so, the chip is correctly seen by Raspberry.
To test if the display is working you can execute a test script :
- cd Adafruit_Python_CharLCD/examples
- sudo ./char_lcd_mcp.py
Some test messages should be displayed on the LCD display.
Troubleshooting
It is possible to have some problems installing the libraries.Here a couple of tips and resolutions.
apt-get missing
If you start from a fresh installation of Raspbian, especially a lite version, before to start to follow the instructions above, be sure to execute :
- sudo apt-get update
- sudo apt-get upgrade
- sudo apt-get update
It is important because updating the first time, include more repo on apt-get.
python build fail
If during the python building of the library you have this errors :
python ./setup.py build
Downloading https://pypi.python.org/packages/source/s/setuptools/setuptools-3.5.1.zip
Extracting in /tmp/tmpw6UbTx
Traceback (most recent call last):
File "./setup.py", line 4, in
use_setuptools()
File "/home/pi/Adafruit_Python_CharLCD/ez_setup.py", line 128, in use_setuptools
return _do_download(version, download_base, to_dir, download_delay)
File "/home/pi/Adafruit_Python_CharLCD/ez_setup.py", line 108, in _do_download
_build_egg(egg, archive, to_dir)
File "/home/pi/Adafruit_Python_CharLCD/ez_setup.py", line 57, in _build_egg
with archive_context(archive_filename):
File "/usr/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/home/pi/Adafruit_Python_CharLCD/ez_setup.py", line 88, in archive_context
with get_zip_class()(filename) as archive:
File "/usr/lib/python2.7/zipfile.py", line 770, in __init__
self._RealGetContents()
File "/usr/lib/python2.7/zipfile.py", line 813, in _RealGetContents
raise BadZipfile, "File is not a zip file"
zipfile.BadZipfile: File is not a zip file
this happens because for some magic reason :) the python script screw up the download of a zipped file.
In my case the file was setuptools-3.5.1.zip.
Doing an ls -l showed up to be 122 byte big !! Definitively NOT a zip file.
The workaround was quite easy actually.
The workaround was quite easy actually.
- remove the file : sudo rm setuptools-3.5.1.zip
- manually download the file :
wget https://pypi.python.org/packages/source/s/setuptools/setuptools-3.5.1.zip - Re-execute the build : sudo python ./setup.py build
Examples
Be aware about the type of kit you are using.
On the examples area there are different examples depending the type of display in use.
To test the basic display, use : char_lcd_mcp.py
To test the kit with RGB display and pushbutton use : char_lcd_plate.py
Subscribe to:
Posts (Atom)






