Welcome to Laser Pointer Forums - discuss green laser pointers, blue laser pointers, and all types of lasers

LPF Donation via Stripe | LPF Donation - Other Methods

Links below open in new window

ArcticMyst Security by Avery

LPM project - help needed

Benm

0
Joined
Aug 16, 2007
Messages
7,896
Points
113
Nah, those capacitors really are not all that critical - 10 and 22 pF is commonly used. Most crystals are designed to operated at rated frequency with a total paralel capacity in the order of 20 or 30 pF. Using larger capacitors in the 10 MHz range won't usually matter much, even if you go for 33 or 47 pF. It might shift the frequency down a couple of PPM, but everything will still be in sync and oscillate just fine.
 





Joined
Sep 20, 2008
Messages
17,622
Points
113
I just looked at the Data Sheet for the ADC and the IC has an internal
oscillator for conversion and the Osc Pin on the IC is an output pin if used
that way... I don't think you need a 2nd Oscillator....

The MCU oscillator should supply the timing for the I2C clocking...

BTW you can put 2pc 10pf caps in parallel for 20pf...


Jerry
 
Joined
Feb 5, 2008
Messages
6,252
Points
83
Nah, those capacitors really are not all that critical - 10 and 22 pF is commonly used. Most crystals are designed to operated at rated frequency with a total paralel capacity in the order of 20 or 30 pF. Using larger capacitors in the 10 MHz range won't usually matter much, even if you go for 33 or 47 pF. It might shift the frequency down a couple of PPM, but everything will still be in sync and oscillate just fine.
Thanks for the info buddy, but one more thing...

How is the crystal connected to the PFC ADC?

If EXT pin is on ground, then internal one is used and you can read the frequency from OSC pin.
However, if EXT is on 5V supply then you can feed the external clock input to the OSC.
I don't quite get it how - please somebody explain that.

EDIT - Didn't see your reply Jerry.

Still I have this KHz measurement on my DMM, measuring the ends of the crystal shows 0.050 KHz for some reason, and measring the ground and OSC of ADC flies off the measuring range, so it's greater than KHz.

Something is wrong and it's right under my now and I cannot figure out what!

EDIT 2 - if EXT is connected to 5V supply, can SCL be then connected as input for the clock?
Just to make sure they work on the same floor - or must it be some other oscillator?

I haven't asked so many blind questions since Feb 2008 ...


EDIT 3 - Well I did not mess with oscillators or anything, well here is the situation so if anybody thinks of something let me know.
PCF ADC , basically ALL pins grounded except
Vcc - 5V supply
Vref - to Vcc, 5V
A in 0 - input from TEC->OPAMP + (negative from opamp is grounded)
OSC floating
SCL and SDA to theri respetive MCU ports.

A segment of Display 1 (the one for the hundreds) blinking in repetative patters, which is around 2 or 3 times very fast the rests for a second, pattern disrupted by shining a laser on TEC or similar temperature change provoing.

Opamp functional, MCU 90% sure functional.

If somebody has apsolutely ANY ideas besides "throw it out the window" let me know real fast - I gotta catch some Z's.
 
Last edited:

Benm

0
Joined
Aug 16, 2007
Messages
7,896
Points
113
I can't see whats going on on your end, and i'm no ARM buff either... so its hard to judge if your problem is in software or hardware from this end.

You should probably do tests using reference voltages instead of the tec output, just to see if the entire unit is working as expected, taking out as many uncertain factors as you possibly can. It can be a very tedious approach, but often its the only way to find what is at fault exactly... sometimes its just a stupid wiring error, that seems impossible to isolate unless you look at every single step in detail.
 
Last edited:
Joined
Feb 5, 2008
Messages
6,252
Points
83
I can't see whats going on on your end, and i'm no ARM buff either... so its hard to judge if your problem is in software or hardware from this end.

You should probably do tests using reference voltages instead of the tec output, just to see if the entire unit is working as expected, taking out as many uncertain factors as you possibly can. It can be a very tedious approach, but often its the only way to find what is at fault exactly... sometimes its just a stupid wiring error, that seems impossible to isolate unless you look at every single step in detail.
Well that's what I was doing. Trust me the TEC and acompanyign opamp are working, and MCU is working since I had the chance to check it wil O-scope , it is visible it's sending the request for data over I2C and it's lighting up the segments, well, only one of them.
The only one to blame is ADC it seems - no other logical explanation as I have pretty much ruled everything else out.

I'm just gonna have to try to rewire it differently and maybe I get lucky ...

EDIT - The reason I am avoiding the belief in the software fault is the one that in the event of software fault - I cannot do anything , so I'm pretty much doomed.
I have a code for the MCU, .c file, cn open in notepad ,if anybody wants to take a look.
 
Last edited:
Joined
Feb 5, 2008
Messages
6,252
Points
83
Well folks this is it, I've reached the end of the line, I'm facing a concrete wall with no obvious way out -
meaning -
I've triple checked every single trace on the damned PCB now - read through datasheets, and reached the most unfortunate conclusion, that the MCU coding is wrong on some way.

So, here is the schematic of all things now on my PCB:
LPMsch.jpg

Note, Aout on ADC is also grounded, and two pull up resistors are used on I2C buses, SDA and SCL.

Here is the code running in MCU:
#include <reg51.h>

sbit SDA = P1^0;
sbit SCL = P1^1;
unsigned char Adr_w= 0x90;
unsigned char Adr_r= 0x91;
unsigned char Ctrl_b= 0x00;
unsigned char ADval= 0;
unsigned char c;
unsigned char stotice, desetice, jedinice;
polje[] ={0x7E, 0x0C, 0xB6, 0x9E, 0xCC, 0xDA, 0xFA, 0x0E, 0xFE, 0xDE};
#include <i2c_lib.c>
/****************************************************************************/
void waitms(unsigned int ms)
{
unsigned int loop1, loop2;
for (loop1=1; loop1 < ms; loop1++)
{
for (loop2=1; loop2 < 100; loop2++)
{

}
}
}
/**********************************************************************/
main()
{
i2c_start();
i2c_send_Data(Adr_w);
i2c_send_Data(Ctrl_b);
i2c_stop();
while (1)
{
i2c_start();
i2c_send_Data(Adr_r);
ADval=i2c_get_Data(0);
i2c_stop();
ADval = ADval * 2;
stotice = ADval / 100;
desetice = (ADval % 100) / 10;
jedinice = (ADval % 100) % 10;
P0 = jedinice;
P2 = desetice;
P3 = stotice;
waitms(70);
}
}

If ANYBODY has apsolutely ANY idea, post away - I've exhaused all my ideas.

Problem is a bit more serious than just hobby project -
This is my senior schools project. Tomorrow I'd better present it working -

Yeah, I screwed up BIGTIME, I always get to work in the last second.

My fault entirely, but I could sure as hell use some help right now :(
 
Last edited:

Benm

0
Joined
Aug 16, 2007
Messages
7,896
Points
113
Do you have some inline debugger in there.. so you can see what is returned by
i2c_get_Data(0); ?

I'm not familiar with your ADC, perhaps it needs to be set up differenty for measurement times and/or ranges to work properly. I'm more into PIC's myself, those have built-in ADC's that are easier to configure.
 
Joined
Feb 5, 2008
Messages
6,252
Points
83
Do you have some inline debugger in there.. so you can see what is returned by
i2c_get_Data(0); ?

I'm not familiar with your ADC, perhaps it needs to be set up differenty for measurement times and/or ranges to work properly. I'm more into PIC's myself, those have built-in ADC's that are easier to configure.
You mean, AVR line for Atmels ?
Yeah, well, problem is that I had to buy what I could work with, the only programmer board available in immediate sorroundings is for 8051 based Atmel MCUs so I had to use that, and we had some sort of circuit using similar ADC-MCU setup, though that one was returning numbers 0-255 (depending on ADC input) to the serial port, they were read by a software used to communicate with MCUs.

Get_Data 0 , I have no idea what it does, basically me and professor reworked the code used in project mentioned above to use 3x 7seg displays instead of serial port output - though, it would appear, it was a bad idea :(
IIRC there is a get data 1 above that also, so getting data stops for a moment to display the result to LED display, and then swiches back to 1 for data aqusition , though that's just some plain logic, no experience involved, so I could be, and most likely am, wrong.

Oh yeah, one more thing I just noticed ,
"polje" (croatian for "Field), where hexadecimal codes for segment setups are written, is not being used anywhere else in the code at all , where those hexa values MUST be outputted to the ports 0, 2 and 3 somewhere to light up displays in such a manned that digits are formed.
 
Last edited:
Joined
May 31, 2009
Messages
3,239
Points
63
I have no experience with programming IC's but I do have some experience in C++

The only thing I can think of (mainly cause I don't understand the language) is that you do not have a condition for the while loop

#include <reg51.h>

sbit SDA = P1^0;
sbit SCL = P1^1;
unsigned char Adr_w= 0x90;
unsigned char Adr_r= 0x91;
unsigned char Ctrl_b= 0x00;
unsigned char ADval= 0;
unsigned char c;
unsigned char stotice, desetice, jedinice;
polje[] ={0x7E, 0x0C, 0xB6, 0x9E, 0xCC, 0xDA, 0xFA, 0x0E, 0xFE, 0xDE};
#include <i2c_lib.c>
/************************************************** **************************/
void waitms(unsigned int ms)
{
unsigned int loop1, loop2;
for (loop1=1; loop1 < ms; loop1++)
{
for (loop2=1; loop2 < 100; loop2++)
{

}
}
}
/************************************************** ********************/
main()
{
i2c_start();
i2c_send_Data(Adr_w);
i2c_send_Data(Ctrl_b);
i2c_stop();

while (1)
{
i2c_start();
i2c_send_Data(Adr_r);
ADval=i2c_get_Data(0);
i2c_stop();
ADval = ADval * 2;
stotice = ADval / 100;
desetice = (ADval % 100) / 10;
jedinice = (ADval % 100) % 10;
P0 = jedinice;
P2 = desetice;
P3 = stotice;
waitms(70);
}
}

What is the output of the red section?
 
Joined
Feb 5, 2008
Messages
6,252
Points
83
I2C bus operates in exact manner,
Such that MCU first sends the Adress and control bits (which are the ones in red there, I believe) , and only after that the outside device responds with ACK (aknowledge) Bit, followed by one byte of data, and the entire loop is repeating as many times as neccesary which may be coded or infine loop type.

That's what I remember from my classes in school, since I needed to use that, it stayed here in this lump on my shoulders.

EDIT: OH, and... thanks for your help, everybody :thanks:
 
Joined
Nov 22, 2008
Messages
1,506
Points
48
While (1) is an infinite loop and is a legitimate way of running the LPM. If it's easy/quick to update the firmware, might I suggest you do the following:
  • Can you make one of the unused pins switch every loop and hook up an LED?
    (while (1){pin1=boolean; boolean=!boolean; ) in pseudocode
  • Can you also cycle through all of the numbers before the main loop starts? Just go through 1-9 on each 7seg display, waiting 100ms between each?
(Also, is it necessary to close and re-open the i2c port each time?)

Did you go through and configure the "fuses" of the chip to match the timings on the oscillator? I'm not sure if this is even applicable for Atmels but I know it is for PICs.


As I understand it, the 7seg display is controlled by 3 darlington array ICs? If so, you will need to make a new function to control which of the 7 segments is lit - does P0,P2,P3 refer to a pin? If so that's incorrect, you need a way to convert the number into ons and offs on the display. Unless that is affected by some other library or function.

(Sorry for the messiness of this post, I'm just throwing ideas out at this point)
 
Last edited:
Joined
Feb 5, 2008
Messages
6,252
Points
83
While (1) is an infinite loop and is a legitimate way of running the LPM. If it's easy/quick to update the firmware, might I suggest you do the following:

Can you make one of the unused pins switch every loop and hook up an LED?
(while (1){pin1=boolean; boolean=!boolean; ) in pseudocode
Can you also cycle through all of the numbers before the main loop starts? Just go through 1-9 on each 7seg display, waiting 100ms between each?

(Also, is it necessary to close and re-open the i2c port each time?)

Did you go through and configure the "fuses" of the chip to match the timings on the oscillator? I'm not sure if this is even applicable for Atmels but I know it is for PICs.


As I understand it, the 7seg display is controlled by 3 darlington array ICs? If so, you will need to make a new function to control which of the 7 segments is lit - does P0,P2,P3 refer to a pin? If so that's incorrect, you need a way to convert the number into ons and offs on the display.
While your knowledge on the subject is undeniable, so is my unability to use it, I am afraid.

You see, I like in small town which is 85 kilometers, or 2hour train ride away from the city I go to school in.
The programmer board for MCU is at school.
I am at home now.
My next visit to school will be tomorrow, when I have to present my work.

However - I am not doing the work only for the damned school, but for myself also - so basically everything you folks say will be used , if not before - then after the presentation to get this thing working and measuring some lasers.

When I take out the MCU from it's socket, and put one wire on +5V pin, and sweep it across the output ports (of the socket, where MCU is supposed to be ), the segments light up accordingly and respectively to ports touched, so there is no denying that the circuitry itself is alright.

I do not know what are the "fuses" you are mentioning please elaborate a bit more :)

Do you see the line :
Polje [] = { ..... } in the code?
The hexadecimal values in there , when converted to binary data corespond to segments that need to light up, for instance,
0xFF corresponds to
11111111
Each of the bits represent the segments in following order
A B C D E F G DP
which means that
FF
will light up all segments .

If for instance FE was to be used, all segments would light up except decimal point.
Decimal point never used though.


Wiring has been done on the schematic for ease of coding so ports x.1 - x.7 correspond to segment A-G (decimal point not used, port x.0 not used).

So no, P0, 2 and 3 are not pins, but ports, of which each contain 8 pins, but pin #0 is never used, leaving 1-7 pins for segments A-G (no DP).

"Stotice" , "desetice" and "jedinice" are croatian words for hundreds, tens, and ... how'd ya call it, displays the smalles-weight digit?

Anyhow, there are formulas for calculating those values from given input from ADC, for instance,
If ADC gives "123",
[First the value is multiplied by 2 (so I get range 0-510mW instead of 0-255mW, but 2 mW resolution, however Ignoring this part in my example for ease of understanding)]
Then, it's devided by 100, result is "hundreds", in our example, 1
Then, MOD 100 (result is number after decimal point, hence = 23), and then devided by 10, to get value of 2
Then MOD 100 to get 23, then MOD 10 to get = 3.

Numbers then should be sent to their respective ports...
Which is the three lines following,
P0 = ...
P2 = ...
P3 = ...
Name the values however you want, me and professor used croatian words.

Value of ADval (aquired data from ADC), midn you, is not Char as defined up there, me and professor changed it to Integer later, hwoever this is the code I saved in my email.

EDIT - PLEASE take into account what I've mentioned before, that i suspect that the "Polje []" is never actually used to define digits, before sending them to the ports, hence, no output comes, except brief flashes of A segment in Display1 (hundreds) and segment B in Display 2 (tens)
Polje[]is only defined there at the beggining but never actually used.
Is that correct?
 
Last edited:
Joined
Nov 22, 2008
Messages
1,506
Points
48
In that case should you be writing
P0 = polje[jedinice];
P2 = polje[desetice];
P3 = polje[stotice];
instead? This gives the correct effect, I think, presuming P0,P2 and P3 work in this way - maybe an atmel expert can confirm? Perhaps you have to configure which pins are assigned to which ports?

jednice = hundreds
desetice = tens
stotice = units (ones)

I understood the modulus (number conversion) stage, and looks like it's fine, but I'm no expert. That's my first thought, but I don't know how the ports work, so an expert should correct. I'll have another look soon, and see if I spot anything else.

Regarding fuses, I don't know much about them but as far as I know, I think they set low-level settings, such as which power modes and timing settings the chip uses. You might have an issue with them?
 
Last edited:
Joined
Feb 5, 2008
Messages
6,252
Points
83
In that case should you be writing
P0 = polje[jedinice];
P2 = polje[desetice];
P3 = polje[stotice];
instead? This gives the correct effect, I think, presuming P0,P2 and P3 work in this way - maybe an atmel expert can confirm? Perhaps you have to configure which pins are assigned to which ports?

jednice = hundreds
desetice = tens
stotice = units (ones)

I understood the modulus (number conversion) stage, and looks like it's fine, but I'm no expert. That's my first thought, but I don't know how the ports work, so an expert should correct. I'll have another look soon, and see if I spot anything else.
I think you may be right!

Well anyway, I have to give presentation to my work at aound 5 PM, and I'm there around noon, so if I can reach professor on his cellphone I can bring this to his attention and have him change the code and reflash the MCU!
Holy sh*t, imagine me walking into the room
"This is my final schools work which I completed 5 minutes ago" :D

Aoh and, stotice = hundreds
Jedinice = units,

But generally, I think you got it. It should work.
However, the code did compile , and flashed the MCU, if
P0 = desetice is incorrect, wouldn't the compiler give an error message?

Or it's not invalid sintax, just maybe used wrong way, as polje[desetice] is ALSO correct, but works for our case, and the other one works for some other case, for example if data "desetice" needs to be sent as binary data to some memory device ...

Makes sense.

You da man, man!

I'm gonna write all this down and show it to my professor tomorrow.

I was never good at programming ... :whistle:

Million x :thanks:
 
Joined
Nov 22, 2008
Messages
1,506
Points
48
Fuses are low-level settings (power settings, debugging enabled/disabled) and most importantly, whether to use the internal or external oscillator. You may need to look into this - but I don't know the specifics I'm afraid. This, the array stuff (the [] code) and whether or not the ports P0, P2, P3 need any configuration or not (which pins each port corresponds with) before use, are the only issues I can see.

I'm not certain if the I2C commands are correct (I see no reason why they wouldn't be right), but I have no experience working with I2C so I can't be sure (perhaps an expert can confirm it?). I'm not sure if you need to start and stop the I2C every time, but again I don't have a clue - and if it works, I wouldn't mess with it. If it doesn't, this may be the next place to look, after investigating the fuses.
 
Joined
Feb 5, 2008
Messages
6,252
Points
83
Fuses are low-level settings (power settings, debugging enabled/disabled) and most importantly, whether to use the internal or external oscillator. You may need to look into this - but I don't know the specifics I'm afraid. This, the array stuff (the [] code) and whether or not the ports P0, P2, P3 need any configuration or not (which pins each port corresponds with) before use, are the only issues I can see.

I'm not certain if the I2C commands are correct (I see no reason why they wouldn't be right), but I have no experience working with I2C so I can't be sure (perhaps an expert can confirm it?). I'm not sure if you need to start and stop the I2C every time, but again I don't have a clue - and if it works, I wouldn't mess with it. If it doesn't, this may be the next place to look, after investigating the fuses.
Yes devices interconnected with I2C buses must switch to high impedance because that is a serial port with no more than two lines that are used by all devices in that network, devices must wait for free time before attempting communication - well, to my knowledge at least.

Analog-digital converter that I use has EXT pin which determines if external or internal oscilator is used, and OSC pin which, if internal oscilator is used, is left floating, or of external oscilator is used, the signal is connected here, on OSC,
The MCU has a crystal properly wired and does not need coding to use it.

Timings and clock for ADC is provided via I2C bus, line SCL is Serial CLock , SDA is Serial DAta - though I could be wrong again.

The first and foremost problem I see is the lack of usage of
"Polje[]" after it's creation in the header - no other.

Ports are configured by the values in "Polje" , which are hexadecimal values corresponding to states of pins, after their conversion to binary form. You can also write the in binary form no problem, but this way it's less to type.

By tomorrow morning we should have all this mess sorted out. Except the one on back side of PCB.
Around ~45+ air wires (jumpers).
On 100x80 mm PCB. Imagine that.
I was literally running out of solder points for +5V rail.

You guys are lucky that I don't have a camera handy , otherwise you'd all get heart attacks from seeing the picture. When I take it, it's going to Fail thread "PCB fail".

Thanks for the help Charliebruce, +1 for that!
 




Top