I/O Expander met I2C

Hallo iedereen,

Voor mijn stage moet ik een bepaald project maken maar ik heb enkele vragen die hier volgens mij wel passen.

Mijn vraag is als volgt: Voor de centrale eenheid van mijn project zou ik gebruik maken van een PIC bijvoorbeeld de PIC18F2550 aangezien ik minimum 16 programmeerbare I/O's nodig hebben en I2C verbinding.
Eén van mijn inputs is een I2C verbinding die van een PC komt en via een FTDI chip wordt omgevormd wordt naar I2C. Met een programmaatje op de PC moeten we met de PC namelijk een keuze kunnen maken tussen 31 vershillende uitgangen dit is wat er via I2C dan wordt doorgestuurd naar de PIC
Ik heb ook een I/O expander nodig omdat ik anders te weinig I/0's heb, ook dit moet gebeuren via I2C.
Ik heb dus 2 verschillende I2C verbindingen nodig maar de meeste PIC's hebben er slechts 1. Vormt dit een probleem of hoe los ik dit het beste op?

Ik heb dit al gevonden op internet.
http://embedded-lab.com/blog/lab-14-inter-integrated-circuit-i2c-commu…

In de bijlage kan je ook een deel van mijn blokschema vinden

Alvast bedankt

Arco

Special Member

Je kunt een MCP23016 nemen. Je kunt beide op dezelfde i2c bus aansluiten, zolang de adressen maar verschillend zijn.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
blackdog

Golden Member

Hi pierreke101

Kijk eens naar deze ic's, goedkoop en goed verkrijgbaar, ik zelf gebruik de MCP23017
http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=11034&mi…

Groet,
Blackdog

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Bedankt voor jullie antwoord.

De I/O expander zelf moet min. 31 uitgangen hebben.
Het is de IC die min. 16 I/O's moet hebben.

Indien ik mij niet vergis heeft de MCP23017 & MCP23016 I/O expanders maar 16 uitgangen mogelijk max.
Of ben ik ergens verkeerd?

Ik heb al wat opzoekingswerk gedaan en ik heb voorlopig dit gevonden.

Voor de I/O expander : PCA9698
Voor de PIC : PIC18F2550

Wat denken jullie hiervan?

[Bericht gewijzigd door Henry S. op dinsdag 7 maart 2017 19:04:32 (24%)

blackdog

Golden Member

Hi,

Je kan de ic's op een eigen adres zetten, dus je kan meerdere ic's op de zelfde i2c bus zetten voor meer out of inputs....
Je kan 8 van deze ic's tegelijk gebruiken!

Groet,
Blackdog

[Bericht gewijzigd door blackdog op vrijdag 25 november 2016 14:34:13 (13%)

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.
Arco

Special Member

PCA9505/PCA9506. Heeft 40 i/o pins.

[Bericht gewijzigd door Arco op vrijdag 25 november 2016 14:36:44 (49%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Dag Blackdog,

Wat bedoel je precies met "je kan de ic's op een eigen adres zetten"?

Ik ben niet helemaal mee met deze redenering.

blackdog

Golden Member

Hi,

De ic's die ik aangeef kan je instellen op 8 verschillende i2c adressen.
Voorstel, lees de datasheet :-)

Groet,
Blackdog

You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.

Bedankt Arco dit zit er een perfecte I/O Expander uit voor mijn toepassing.
Maar het is geen probleem als ik op mijn CU de PIC, de SDA en SCL voor 2 verschillende dingen gebruikt. Namelijk de gegevens van de PC en voor mijn I/O expander aan te sturen?

Dag Blackdog.

Ik zal deze zeker eens doornemen :)
Maar is het niet eenvoudiger om bijvoorbeeld met de I/O expander (PCA9505/PCA9506) te werken?

[Bericht gewijzigd door Henry S. op dinsdag 7 maart 2017 19:05:13 (23%)

Arco

Special Member

Ik zou aanraden i2c eens te bestuderen hoe het werkt... ;)
Je kunt meerdere ic's aansluiten op 1 bus, zolang de adressen maar verschillen, en de bus niet te lang wordt.
http://www.nxp.com/documents/user_manual/UM10204.pdf

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Oké bedankt voor de hulp Arco!
Ik zal dit eens bestuderen.

Hallo iedereen,

Voor een project waarmee ik bezig ben moet ik ik mijn I/O’s van mijn PIC uitbreiden.
Ik maak hier gebruik van een I/O expander met 40 I/0’s (PCA9505). Ik zal van de 40 I/O’s er een 34 tal gebruiken an allemaal als uitgang.
Ik zal deze dus via I2C aansturen via mijn PIC, ik heb slechts 1 device (PCA9505) die gebruikt maakt I2C en ik heb mijn adressen van mijn PCA9505 alle 3 ingesteld op O (A0, A1, A2).

Ik heb al heel wat zitten lezen in de datasheet en sommige dingen zijn mij niet helemaal duidelijk.
De master zal in mijn geval de PIC zijn en de slave de IO expander.
Eest en vooral zal ik een start conditie versturen.
Daarna zal ik het slave adres versturen gevolgd door R/W conditie, in mijn geval is het slave adres van mijn IO expander binair 0100 000 0 (omvormen naar hexadecimaal voor te versturen), aangezien A0, A1 en A2 allemaal 0 zijn en ik wil schrijven naar IO expander.

AFBEELDING 1
?
Daarna zal de slave een acknowledgement versturen. Indien deze goed ontvangen is zal de master (PIC) een byte versturen naar de slave die opgestaan word in het command register. Maar ik versta niet goed hou dit werkt met die auto increment bit…

AFBEELDING 2
?
D.m.v. D0, D1, D2, D3, D4 en D5 zo danig te kiezen als in de datasheet vermeld is kan ik volgens mij mijn poorten als uitgang plaatsen.
?
AFBEELDING 3

Ik ben dus niet helemaal mee hoe ik kan bepalen hoe ik al mijn poorten als uitgang zet en hoe ik die dan effectief hoog of laag maak…

Iemand die mij hierbij kan helpen?

Shiptronic

Overleden

Het gaat dus nog steeds over : https://www.circuitsonline.net/forum/view/134370/3

Waar bij je gisteren ook al een nieuwe post begonnen bent over de PIC met USB. Waarom niet alles in hetzelfde topic (je hebt er nu al een stuk of 6 8) , dan weet iedereen waar het over gaat . Nu staat alle info verspreid en versnippert, of gaan mensen 3x hetzelfde uitleggen.

hier https://www.circuitsonline.net/forum/view/134741 & https://www.circuitsonline.net/forum/view/134739 staat ook hetzelfde, en daar ook weer verspreid over 2 topic's

Wie de vraag stelt, zal met het antwoord moeten leren leven.
Arco

Special Member

De output pin status kun je lezen/schrijven in de OP0...4 registers; in of output kun je kiezen in de IOC0...4 registers.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Hallo iedereen,

Ik ben bezig met het programmeren van mijn I2C functie adhv een mooie tutorial van onderstaande link.
http://www.robot-electronics.co.uk/i2c-tutorial

#define SCL TRISB4 // I2C bus
#define SDA TRISB1 //
#define SCL_IN RB4 //
#define SDA_IN RB1 //

SDA = SCL = 1;
SCL_IN = SDA_IN = 0;

Indien ik vetgedrukte tekst schrijf in mijn programma dan krijg ik om een of andere reden een syntax error, je kan mijn programma terug vinden in de bijlage.

Arco

Special Member

Waarom niet gewoon los?

c code:


SDA = 1;
SCL = 1;
SDA_IN = 0;
SCL_IN = 0;

[Bericht gewijzigd door Arco op maandag 6 maart 2017 10:34:33 (17%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Dag Arco, werkt spijtig genoeg ook niet.
Het probleem ligt ergens aan de C18 compiler ofzo.
Maar geen idee hoe dit op te lossen

Arco

Special Member

Vermelden van de optredende error zou helpen, we zijn niet helderziend... ;)

[Bericht gewijzigd door Arco op maandag 6 maart 2017 10:49:07 (24%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Hahahha das waar ARCO ;)

Syntax ERROR raar genoeg

Heb het al op een andere manier opgelost.

Ik heb gebruik gemaakt van de librarty die aanwezig is voor I2C van de MPLAB C18 compiler (I2C.h)

In mijn main programma heb ik nu gewoon bijvoorbeeld zo iets geschreven.

c code:


IdleI2C(); // Wait until the bus is idle
StartI2C(); // Send START condition
IdleI2C(); // Wait for the end of the START condition
WriteI2C( slave_address & 0xfe ); // Send address with R/W cleared for write
IdleI2C(); // Wait for ACK
WriteI2C( data[0] ); // Write first byte of data
IdleI2C(); // Wait for ACK
// ...
WriteI2C( data[n] ); // Write nth byte of data
IdleI2C(); // Wait for ACK
StopI2C();

En dit lijkt ideaal te werken, een stuk gemakkelijker als alles zelf schrijven

[Bericht gewijzigd door Henry S. op dinsdag 7 maart 2017 19:08:01 (1%)

Arco

Special Member

Library is wel zo handig... ;)
Als je de enige master op de bus bent, zijn al die IdleI2C()'s niet echt nodig...
Ik ben toevallig net met een PCA9506 (= PCA9505 zonder pull-ups) bezig, heel makkelijk aan te sturen gelukkig...

[Bericht gewijzigd door Arco op maandag 6 maart 2017 16:19:11 (34%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Dag Arco,

Is inderdaad een tof ding die PCA950(6) en redelijk eenvoudig aan te sturen :)

Momenteel heb ik dit in mijn MAIN C programma ivm met I2C

c code:


#include<p18f4550.h>
#include "i2c.h"

...

void main(void) {

	OpenI2C (MASTER, SLEW_OFF);
        ....
				IdleI2C();                         // Wait until the bus is idle
				StartI2C();                       // Send START condition
				IdleI2C();                         // Wait for the end of the START condition
				WriteI2C( 0x40 );  		//address from slave with R/W cleared for write (0100 0000)
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x08 );            // Write adress from command register (0000 1000)
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x00 );            // Write data for the command register
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x09 );            // Write adress from command register (0000 1001)
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x00 );            // Write data for the command register
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x0A );           // Write adress from command register (0000 1010)
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x00 );            // Write data for the command register
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x0B );            // Write adress from command register (0000 1011)
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x00 );            // Write data for the command register
				IdleI2C();                          // Wait for ACK
				WriteI2C( 0x0C );            // Write adress from command register (0000 1100)
				IdleI2C();                         // Wait for ACK
				WriteI2C( 0x00 );             // Write data for the command register
				IdleI2C();                         // Wait for ACK
				StopI2C();

                               ...
}

Dit is een voorbeeld waarbij ik al mijn I/O's als output zet en allemaal op 0.
Maar ik weet dat ik nog enkele dingen ontbreek ivm I2C maar ik weet niet goed wat en hoe, ik denk dingen zoals de declaratie van mijn poorten met SCL en SDA en andere dingen maar ik weet niet goed wat...
Kan je mij hierin helpen?

[Bericht gewijzigd door Henry S. op dinsdag 7 maart 2017 19:07:28 (0%)

Arco

Special Member

Daar valt niks aan te declareren, er is maar 1 i2c port en die zit op een vaste plaats...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Super bedankt Arco.

Ik zag namelijk in sommige programma's dat ze dit wel doen maar ik veronderstel dat ze dit dan doen adhv software I2C..

Het programma zoals ik nu schreef zou dus moeten werken?

Hallo iedereen,

Mijn testopstelling is af en ik heb mijn PIC (PIC18F4550) via de I2C pinnen met de IO expander (PCA9505) verbonden.
Voor het testen van de IO expander wens ik gewoon een ledje aan te sturen, schakeling die ik hiervoor gelaakt heb is volledig correct.
Voor het I2C gedeelte van mijn programma het ik gebruik gemaakt van de I2C library van Microchip.
Het programma zelf kan je grotendeels hieronder terug vinden.
Mijn ledje brandt nooit dus het werkt niet...

Iemand die mij kan helpen? volgens mij ontbreek ik nog wat code voor de I2C verbinding..
Moet ik mijn 2 I2C pinnen (SDA en SCL) niet declareer dat ik hen zo zal gebruiken en niet als IO's? of wat ontbreek ik

#include<p18f4550.h>
#include "i2c.h"

...

void main(void) {

OpenI2C (MASTER, SLEW_OFF);
....
IdleI2C(); // Wait until the bus is idle
StartI2C(); // Send START condition
IdleI2C(); // Wait for the end of the START condition
WriteI2C( 0x40 ); //address from slave with R/W cleared for write (0100 0000)
IdleI2C(); // Wait for ACK
WriteI2C( 0x08 ); // Write adress from command register (0000 1000)
IdleI2C(); // Wait for ACK
WriteI2C( 0xFF ); // Write data for the command register (Set al outputs from this register High, hierop is mijn led aangesloten
IdleI2C(); // Wait for ACK
WriteI2C( 0x09 ); // Write adress from command register (0000 1001)
IdleI2C(); // Wait for ACK
WriteI2C( 0x00 ); // Write data for the command register
IdleI2C(); // Wait for ACK
WriteI2C( 0x0A ); // Write adress from command register (0000 1010)
IdleI2C(); // Wait for ACK
WriteI2C( 0x00 ); // Write data for the command register
IdleI2C(); // Wait for ACK
WriteI2C( 0x0B ); // Write adress from command register (0000 1011)
IdleI2C(); // Wait for ACK
WriteI2C( 0x00 ); // Write data for the command register
IdleI2C(); // Wait for ACK
WriteI2C( 0x0C ); // Write adress from command register (0000 1100)
IdleI2C(); // Wait for ACK
WriteI2C( 0x00 ); // Write data for the command register
IdleI2C(); // Wait for ACK
StopI2C();

...
}

Arco

Special Member

De i2c pinnen moet je wel als ingang zetten (TRISx register). Kan zijn dat die i2c library het voor je doet, maar da's niet zeker...
Je zet de expander pinnen ook niet als output (register 0x18...0x1C)
Ik gebruik dit in Mikrobasic:

pic basic code:


  I2CStart()                       'Initialize 
  I2CWrite(0x40)                   'Address
  I2CWrite(0x18+0x80)              'Reg[0x18] with auto increment
  I2CWrite(%00000000)              'Port 0 output
  I2CWrite(%00000000)              'Port 1 output
  I2CWrite(%00000000)              'Port 2 output
  I2CWrite(%00000000)              'Port 3 output
  I2CWrite(%00000000)              'Port 4 output
  I2CRestart()                     'Bus restart
  I2CWrite(0x40)                   'Address
  I2CWrite(0x08+0x80)              'Reg[0x08] with auto increment
  I2CWrite(%11111111)              'Set port 0 all pins high
  I2CWrite(%00000000)              'Set port 1 all pins low
  I2CWrite(%00000000)              'Set port 2 all pins low
  I2CWrite(%00000000)              'Set port 3 all pins low
  I2CWrite(%00000000)              'Set port 4 all pins low
  I2CStop()                        '
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com