|
|
View previous topic :: View next topic |
Author |
Message |
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Mon Dec 02, 2019 7:34 am |
|
|
My current code is the same code as above.
The only difference
Code: |
#define FDC2214_RCOUNT_CH0 0x08 //0x400
|
Code: |
if (chanMask & 0x01) {
//settle count maximized, slow application
write16FDC(FDC2214_SETTLECOUNT_CH0, 0x6400); // 0x6400
//rcount maximized for highest accuracy
write16FDC(FDC2214_RCOUNT_CH0, 0x400); //0xFFFF
//no offset
write16FDC(FDC2214_OFFSET_CH0, 0x0000);
// Set clock dividers
write16FDC(FDC2214_CLOCK_DIVIDERS_CH0, 0x2001); //0x2001
//set drive register
write16FDC(FDC2214_DRIVE_CH0, 0xF800); //0xF800
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Mon Dec 02, 2019 7:41 am |
|
|
What was it giving with the 28bit chip?.
If you haven't actually tried this, it probably means you need to raise
fRef to bring the output down. You circuit is almost certainly producing
too much capacitance for the selected Fref. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Mon Dec 02, 2019 7:53 am |
|
|
Quote: |
17:02:48.451 -> 14344019,14836662,14469903,14257900
17:02:48.794 -> 14323142,14836626,14471291,14261382
17:02:49.135 -> 14701915,14836605,14471031,14261227
17:02:49.438 -> 14595591,14836249,14471284,14261085
17:02:49.815 -> 14170835,14836270,14471156,14261172
17:02:50.122 -> 13968915,14835509,14470934,14257636
17:02:50.465 -> 13967938,14835581,14470969,14261248
17:02:50.774 -> 13952396,14836057,14470173,14261570
17:02:51.120 -> 13949209,14835978,14471156,14261099
17:02:51.462 -> 14504624,14835659,14470340,14260271
17:02:51.806 -> 14556380,14836284,14471325,14259846
17:02:52.117 -> 14581438,14835709,14471003,14260056
17:02:52.464 -> 14672772,14836086,14470737,14257460
17:02:52.775 -> 14698352,14836904,14471474,14261066
17:02:53.122 -> 14703193,14836960,14471021,14260438
17:02:53.466 -> 14704417,14837401,14471474,14260109
|
It gave these values.
See for example the first channel.
When the normal value is 14 .., when the plot approaches, it becomes 13 .. When the object moves away, it recovers. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Mon Dec 02, 2019 9:44 am |
|
|
OK. If everything is set the same as it was for the 28bit code, except the
value fed to CH0_RCOUNT, it should be returning about 173. Have you tried with the second read included, but the result just thrown away?. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Tue Dec 03, 2019 12:03 am |
|
|
Do you mean the second reading CH0_LSB?
Yeah, I read and I didn't get results.
173 What do you mean? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Tue Dec 03, 2019 1:07 am |
|
|
Use your existing 28bit code. Except:
1) Change the number written to RCOUNT to 0x400.
2)
Replace this:
Code: |
reading = ((unsigned int32) read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA) << 16;
reading |= read16FDC(addressLSB);
//with:
reading=read16FDC(addressMSB);
int16 dummy=read16FDC(addressLSB);
|
The point is the data sheet says there may be issues ulness you read
both words, but on the 12bit chip the first word is the 'result'. So you
need to do a dummy read of the second word. and just throw this
away. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Tue Jan 14, 2020 7:22 am |
|
|
Hello again after a long time.
My integrated was broken. I soldered a new one.
I reorganized the code with the advice of Ttelmah and others.
And it worked properly. Thank you all for that.
But worked on the first try. I didn't make any changes in the second attempt, but it didn't work. After a while it worked again. It was then locked during operation.
The only difference in my new circuit design was to connect the INTB pin to pin a2. I don't want to leave this code created with your support without stabilizing it. So I want to read stable values from a single channel and close this title. Thanks in advance for your support.
This Code:
Code: |
// (?) I'm not sure about the explanations with this mark
#include <16f1824.h>
//#device ADC=10
#INCLUDE <stdlib.h> //Required to send make16()
#fuses XT,NOWDT,NOBROWNOUT,NOPUT,NOWRT,NODEBUG, NOMCLR//, NOPROTECT, NOWDT, NOLVP,INTRC_IO,
#use delay(clock=4000000) //When you do 8, 16 or 32 you do not get a result
#use rs232(baud=9600,parity=N,xmit=PIN_C4,rcv=PIN_C5,bits=8)
#use i2c(Master,sda=PIN_c1,scl=PIN_c0,slow=400000,FORCE_HW)
//----------------------------------------------
///////////////////fdc221 datasheet page 22///////////////////////
// Address is 0x2A = 0x54 (default) or 0x2B = 0x55 (if ADDR is high)
#define FDC2214_I2C_ADDR_0 0x54
#define FDC2214_I2C_ADDR_1 0x55
//bitmasks
#define FDC2214_CH0_UNREADCONV 0x0008 //denotes unread CH0 reading in STATUS register
#define FDC2214_CH1_UNREADCONV 0x0004 //denotes unread CH1 reading in STATUS register
#define FDC2214_CH2_UNREADCONV 0x0002 //denotes unread CH2 reading in STATUS register
#define FDC2214_CH3_UNREADCONV 0x0001 //denotes unread CH3 reading in STATUS register
//registers
#define FDC2214_DEVICE_ID 0x7F
#define FDC2214_MUX_CONFIG 0x1B
#define FDC2214_CONFIG 0x1A
#define FDC2214_RCOUNT_CH0 0x08
#define FDC2214_RCOUNT_CH1 0x09
#define FDC2214_RCOUNT_CH2 0x0A
#define FDC2214_RCOUNT_CH3 0x0B
#define FDC2214_OFFSET_CH0 0x0C
#define FDC2214_OFFSET_CH1 0x0D
#define FDC2214_OFFSET_CH2 0x0E
#define FDC2214_OFFSET_CH3 0x0F
#define FDC2214_SETTLECOUNT_CH0 0x10
#define FDC2214_SETTLECOUNT_CH1 0x11
#define FDC2214_SETTLECOUNT_CH2 0x12
#define FDC2214_SETTLECOUNT_CH3 0x13
#define FDC2214_CLOCK_DIVIDERS_CH0 0x14
#define FDC2214_CLOCK_DIVIDERS_CH1 0x15
#define FDC2214_CLOCK_DIVIDERS_CH2 0x16
#define FDC2214_CLOCK_DIVIDERS_CH3 0x17
#define FDC2214_STATUS 0x18
#define FDC2214_DATA_CH0_MSB 0x00
#define FDC2214_DATA_CH0_LSB 0x01
#define FDC2214_DATA_CH1_MSB 0x02
#define FDC2214_DATA_CH1_LSB 0x03
#define FDC2214_DATA_CH2_MSB 0x04
#define FDC2214_DATA_CH2_LSB 0x05
#define FDC2214_DATA_CH3_MSB 0x06
#define FDC2214_DATA_CH3_LSB 0x07
#define FDC2214_DRIVE_CH0 0x1E
#define FDC2214_DRIVE_CH1 0x1F
#define FDC2214_DRIVE_CH2 0x20
#define FDC2214_DRIVE_CH3 0x21
// mask for 28bit data to filter out flag bits
#define FDC2214_DATA_CHx_MASK_DATA 0x0FFF
#define FDC2214_DATA_CHx_MASK_ERRAW 0x1000
#define FDC2214_DATA_CHx_MASK_ERRWD 0x2000
//------------------------------------------------
///////////////////////////////////////////////////////////////////
#define CHAN_COUNT 2 // channel number
char dev_adds = FDC2214_I2C_ADDR_0; //dev_adds = 0x54
// fdc2214 datasheet steps on page 22 followed
void write16FDC(unsigned int16 address, unsigned int16 data) {
i2c_start();
i2c_write(dev_adds); //first, sending integrated address
i2c_write(address & 0xff); //secondly, sending register address
// (?) Masked with 0xff, to ensure that 8 bits are sent
i2c_write(data >>8); //i2c communicates with 8 bits. But data = 16 bits.
//so we're shifting
i2c_write(data);
//other 8 bits
i2c_stop();
}
// fdc2214 datasheet steps on page 22 followed
unsigned int16 read16FDC(char address) {
unsigned int16 data;
i2c_start();
i2c_write(dev_adds);
i2c_write(address);
i2c_start();
i2c_write(dev_adds + 1); // Set R/W bit = 1 to read bytes
char datahigh=i2c_read(); //two pieces made from 8 bits to 16 bits
char datalow=i2c_read(0);
data=make16(datahigh,datalow);
i2c_stop();
return data;
}
///////////////////////////////////////////////////////////////////////////////
void loadSettings(char chanMask, char autoscanSeq, char deglitchValue, int1 intOsc);
int1 FDC2214_begin(char chanMask,char autoscanSeq, char deglitchValue, int1 intOsc) {
printf("FDC2214_begin");
int devId = read16FDC(FDC2214_DEVICE_ID);
//Checking the lighting of the device on the i2c line (sda, scl).
//If the values 0x3054 and 0x3055 are displayed; connected to the correct device
if (devId != 0x3054) {
if (devId != 0x3055) {
//two valid device ids for FDC2214 0x3054 and 0x3055
return false;
}
}
loadSettings(chanMask, autoscanSeq, deglitchValue, intOsc);
return true;
}
///////////////////////////////////////////////////////////////////////////////
void loadSettings(char chanMask, char autoscanSeq, char deglitchValue, int1 intOsc) {
//Adjusting configuration settings
// When the FDC powers up, it enters into Sleep Mode and will wait for configuration.
//Once the device is configured, exit Sleep Mode by setting CONFIG.
printf("loadSettings");
if (intOsc) {
write16FDC(FDC2214_CONFIG, 0x1C81); //set config 0x1C81
printf("0x1C81");
} else {
write16FDC(FDC2214_CONFIG, 0x1E81); //set config 0x1E81
printf("0x1E81");
}
//FDC2214 HAVE 4 CHANNEL
//We make configuration settings for each channel.
//If channel 1 selected, init it..
if (chanMask & 0x01) {
//settle count maximized, slow application
write16FDC(FDC2214_SETTLECOUNT_CH0, 0x6400); // 0x6400
//rcount maximized for highest accuracy
write16FDC(FDC2214_RCOUNT_CH0, 0x400); //0xFFFF
//no offset
write16FDC(FDC2214_OFFSET_CH0, 0x0000);
// Set clock dividers
write16FDC(FDC2214_CLOCK_DIVIDERS_CH0, 0x2001); //0x2001
//set drive register
write16FDC(FDC2214_DRIVE_CH0, 0xF800); //0xF800
}
// Init chan2, if selected by channel init mask
if (chanMask & 0x02) {
write16FDC(FDC2214_SETTLECOUNT_CH1, 0x6400);
write16FDC(FDC2214_RCOUNT_CH1, 0x400);
write16FDC(FDC2214_OFFSET_CH1, 0x0000);
write16FDC(FDC2214_CLOCK_DIVIDERS_CH1, 0x2001);
write16FDC(FDC2214_DRIVE_CH1, 0xF800);
}
if (chanMask & 0x04) {
write16FDC(FDC2214_SETTLECOUNT_CH2, 0x6400);
write16FDC(FDC2214_RCOUNT_CH2, 0xFFFF);
write16FDC(FDC2214_OFFSET_CH2, 0x0000);
write16FDC(FDC2214_CLOCK_DIVIDERS_CH2, 0x2001);
write16FDC(FDC2214_DRIVE_CH2, 0xF800);
}
if (chanMask & 0x08) {
write16FDC(FDC2214_SETTLECOUNT_CH3, 0x6400);
write16FDC(FDC2214_RCOUNT_CH3, 0xFFFF);
write16FDC(FDC2214_OFFSET_CH3, 0x0000);
write16FDC(FDC2214_CLOCK_DIVIDERS_CH3, 0x2001);
write16FDC(FDC2214_DRIVE_CH3, 0xF800);
}
/////////////////////////////////////////////////////////////////////////////
unsigned int16 muxVal = 0x0208 | ( (unsigned int16)autoscanSeq << 13) | deglitchValue;
//(?) I have no idea what's going on here.
write16FDC(FDC2214_MUX_CONFIG, muxVal); //set mux config for channels
// write16FDC(FDC2214_CONFIG, 0);
}
unsigned int32 getReading28(char channel) {
// Serial.println("getReading28");
int timeout = 100;
unsigned int32 reading = 0;
int status = read16FDC(FDC2214_STATUS);
char addressMSB;
char addressLSB;
char bitUnreadConv;
// Set to channel selection, we match registers with variables.
switch (channel) {
case 0:
addressMSB = FDC2214_DATA_CH0_MSB;
addressLSB = FDC2214_DATA_CH0_LSB;
bitUnreadConv = FDC2214_CH0_UNREADCONV;
break;
case 1:
addressMSB = FDC2214_DATA_CH1_MSB;
addressLSB = FDC2214_DATA_CH1_LSB;
bitUnreadConv = FDC2214_CH1_UNREADCONV;
break;
case 2:
addressMSB = FDC2214_DATA_CH2_MSB;
addressLSB = FDC2214_DATA_CH2_LSB;
bitUnreadConv = FDC2214_CH2_UNREADCONV;
break;
case 3:
addressMSB = FDC2214_DATA_CH3_MSB;
addressLSB = FDC2214_DATA_CH3_LSB;
bitUnreadConv = FDC2214_CH3_UNREADCONV;
break;
default: return 0;
}
//(?)
while (timeout && !(status & bitUnreadConv)) {
status = read16FDC(FDC2214_STATUS);
timeout--;
}
if (timeout == 100) {
reading=read16FDC(addressMSB);
int16 dummy=read16FDC(addressLSB);
//reading = ((unsigned int32) read16FDC(addressMSB) & FDC2214_DATA_CHx_MASK_DATA) << 16;
// reading |= read16FDC(addressLSB);
while (timeout && !(status & bitUnreadConv)) {
status = read16FDC(FDC2214_STATUS);
timeout--;
// PUTC(status);
}
}
if (timeout) {
//read the 28 bit result
reading=read16FDC(addressMSB);
int16 dummy=read16FDC(addressLSB);
return reading;
} else {
// Could not get data, chip readynes flag timeout
return 0;
}
}
///////////////////////////////////////////////////////////////////////////////
INT8 k[20];
void main() {
set_tris_a(0xfe);
setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_PLL_ON);
delay_ms(10000); // this not necessary
int1 capOk = FDC2214_begin(0xF, 0x0006, 0x5, true); //again config
//int1 capOk = FDC2214_begin(0x3, 0x4, 0x5, TRUE);
//setup all four channels, autoscan with 4 channels, deglitch at 10MHz, external oscillator
if (capOk) //we check whether it is connected
printf("open");
else
printf("close");
//////////////////////////
while(true) {
printf("close");
unsigned int32 capa[CHAN_COUNT]; // variable to store data from FDC
for (int i = 0; i < CHAN_COUNT; i++) { // for each channel
// ### read 28bit data
// getReading28(reading);
capa[i] = getReading28(i); //
// ### Transmit data to serial in simple format readable by SerialPlot application.
printf("%lu ",capa[i]);
if(i==1) // printing the data we read to the bottom line
{
printf("\n");
}
if (i < CHAN_COUNT - 1) printf(",");
else printf("");
}
delay_ms(100);
if(pin_A5) // fdc2112 INTB Control
output_high(pin_c2);
else
output_low(pin_c2);
}}
| |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 14, 2020 9:57 pm |
|
|
Your code has multiple defects. The compiler warnings show the lines that
have problems:
Quote: |
Warning 203 "...\PCM_TEST.c" Line 102(1,1): Condition always TRUE
Warning 203 "...\PCM_TEST.c" Line 103(1,1): Condition always TRUE
Warning 203 "...\PCM_TEST.c" Line 264(1,1): Condition always TRUE
Warning 202 "...\PCM_TEST.c" Line 209(7,12): Variable never used: dummy
Warning 202 "...\PCM_TEST.c" Line 221(11,16): Variable never used: dummy
Warning 202 "...\PCM_TEST.c" Line 229(6,7): Variable never used: k
Memory usage: ROM=24% RAM=19% - 36%
0 Errors, 6 Warnings.
Build Successful.
|
The first two warnings point to the following lines shown in bold:
Quote: | int1 FDC2214_begin(char chanMask,char autoscanSeq, char deglitchValue, int1 intOsc) {
printf("FDC2214_begin");
int devId = read16FDC(FDC2214_DEVICE_ID);
//Checking the lighting of the device on the i2c line (sda, scl).
//If the values 0x3054 and 0x3055 are displayed; connected to the correct device
if (devId != 0x3054) {
if (devId != 0x3055) {
//two valid device ids for FDC2214 0x3054 and 0x3055
return false;
}
}
loadSettings(chanMask, autoscanSeq, deglitchValue, intOsc);
return true;
}
|
But look at the line below. You're reading a 16-bit value, but then you're
putting it into an 8-bit 'int'. That's wrong, because you then compare the
8-bit 'int' with 16-bit constants.
Quote: | int devId = read16FDC(FDC2214_DEVICE_ID); |
Since they are different sizes, the compiler thinks they will always be
unequal, and it declares that your test for inequality will be "Always TRUE".
Let's look at what the compiled code looks like in the .LST file:
Code: | 00FC: MOVLW 7F
00FD: MOVWF address
00FE: CALL read16FDC
00FF: MOVF @78,W
0100: MOVWF devId
..... //Checking the lighting of the device on the i2c line (sda, scl).
..... //If the values 0x3054 and 0x3055 are displayed; connected to...
..... if (devId != 0x3054) {
..... if (devId != 0x3055) {
..... //two valid device ids for FDC2214 0x3054 and 0x3055
..... return false;
0101: MOVLW 00
0102: MOVWF @78
0103: GOTO 1E6
|
There's nothing there. The compiler has optimized the code away.
There is no assembly code for the devId != xxxx lines. It puts 00 in @78
which means it always returns 'False'. That's not what you intended.
This shows the importance of not ignoring Warnings, and the importance
of inspecting the .LST file.
----------------------------
Let's look at the 3rd warning. It points to the line in bold shown below.
Quote: |
if (i < CHAN_COUNT - 1) printf(",");
else printf("");
}
delay_ms(100);
if(pin_A5) // fdc2112 INTB Control
output_high(pin_c2);
else
output_low(pin_c2);
|
You have messed up the if() statement. You really meant to do this:
PIN_A5 is 101 (in decimal). This is from the 16F1824.h file.
So your if() statement is doing this:
Any non-zero value is considered to be "TRUE" by the compiler, so that
statement gets the warning message of "Condition always True".
Again, that's not what you intended.
The other three warnings are for "Variable never used", which are not
going to cause any harm. Looking at those lines, it's no problem. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Wed Jan 15, 2020 12:22 am |
|
|
Thank you PCM programmer
Quote: | You have messed up the if() statement. |
Yes. I noticed this mistake and corrected it. I'm interested in other errors you specify. But the weird thing is:
Today I run the circuit with the above code. And I got a result.
Quote: |
08:51:04.599 -> close4095 ,218
08:51:04.767 -> close4095 ,218
08:51:04.905 -> close4095 ,217
08:51:05.076 -> close4095 ,217
08:51:05.212 -> close4095 ,217
08:51:05.384 -> close4095 ,216
08:51:05.522 -> close4095 ,216
08:51:05.661 -> close4095 ,215
08:51:05.834 -> close4095 ,213
08:51:05.971 -> close4095 ,213
08:51:06.110 -> close4095 ,212
08:51:06.282 -> close4095 ,212
08:51:06.420 -> close4095 ,211
08:51:06.557 -> close4095 ,211
08:51:06.728 -> close4095 ,211
08:51:06.868 -> close4095 ,211
08:51:07.008 -> close4095 ,210
08:51:07.180 -> close4095 ,210
08:51:07.317 -> close4095 ,210
08:51:07.487 -> close4095 ,210
08:51:07.623 -> close4095 ,210
08:51:07.828 -> close4095 ,210
08:51:07.931 -> close4095 ,210
08:51:08.069 -> close4095 ,213
08:51:08.241 -> close4095 ,218
08:51:08.377 -> close4095 ,218
|
It reads the values of both channels. The first channel shows "4095" because I didn't make the capacitor connection. However, the other channel shows "218". The value decreases as the object approaches.
After a minute the serial communication stopped
Quote: |
08:51:28.096 -> close4095 ,218
08:51:28.233 -> close4095 ,218
08:51:28.404 -> close
|
When I energize the circuit for the second time, the program never starts.
It just writes this.(line 98)
Quote: |
09:04:41.874 -> FDC2214_begin
|
I will correct and check for any errors you specify. However, if the program runs incorrectly the first time and does not run on the second attempt |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 15, 2020 12:51 am |
|
|
ressas wrote: |
However, if the program runs incorrectly the first time and does not run
on the second attempt ?
|
Here are your #fuses. They show you are using a 4 MHz crystal.
Quote: | #include <16f1824.h>
//#device ADC=10
#INCLUDE <stdlib.h> //Required to send make16()
#fuses XT,NOWDT,NOBROWNOUT,NOPUT,NOWRT,NODEBUG, NOMCLR//, NOPROTECT, NOWDT, NOLVP,INTRC_IO,
#use delay(clock=4000000) |
You have the Brownout and Put fuses disabled. Enable them. Re-program
the PIC, then turn off power to the board. Then do your power-up testing again. |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Wed Jan 15, 2020 3:34 am |
|
|
Thank you for your answer. But it didn't happen. I think the integration is a misfortune because the legs are QFN. However, sometimes this does not explain how it works. I'il check the connections again and again. Thank you. I'il get back to you when I get a result. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1910 Location: Norman, OK
|
|
Posted: Wed Jan 15, 2020 8:26 pm |
|
|
You are also missing the ERRORS keyword from the #use rs232 line _________________ Google and Forum Search are some of your best tools!!!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9081 Location: Greensville,Ontario
|
|
Posted: Thu Jan 16, 2020 3:44 pm |
|
|
this...
int1 capOk = FDC2214_begin(0xF, 0x0006, 0x5, true); //again config
I'm surprised doesn't cause an error or at least a warning.
Not supposed to define/create variables inside of main().
There's a couple more... |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Sat Jan 18, 2020 1:00 am |
|
|
dyeatman
What do you mean " ERRORS" For #use rs232 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Sat Jan 18, 2020 1:14 am |
|
|
The #USE RS232, should for a hardware UART, always have the keyword
'ERRORS'. So:
#use rs232(baud=9600,parity=N,xmit=PIN_C4,rcv=PIN_C5,bits=8, ERRORS)
This should (must) always be used, unless your own code contains
routines to handle UART errors. It is an annoyance of mine that several
of the CCS 'examples' set up the UART without this.
On the PIC, if a character arrives and is not handled in time, the 'OERR'
bit is set in the UART. If this happens the UART will be hung, until this
error is cleared. The 'ERRORS' keyword, automatically adds a tiny bit of
extra code to the UART handling, to clear this.
It's one of these things that the 'old hands' here know, and will never code
without..... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|