Loading...
Pages: 1 [2]   Go Down
Author Topic: Identify AC/DC power supply using ATmega328p  (Read 867 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 114
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But some one ( michael_x) says it can be done,

It depends on what "it" is. Powering anything at AC 0v is certainly not possible.

Powering something at AC 230v is certainly possible.

Without knowing what "it" is, it is not possible to tell you what is and isn't possible.

Quote
pls check my code!

Until you have a plan, your code has no meaning.

It is not difficult for a mcu to detect what is powering itself. It is not possible for a mcu to be powered by AC 0v.
Logged

Germany
Offline Offline
Edison Member
*
Karma: 27
Posts: 1486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now i know two functions for that, one FreqCounter library, another pulseIn(). I have an idea about using pulseIn() to implement PSU-frequency-identify. If u read it, pls tell me it does work or doesn't.


Arduino is great for thousands of libraries with example code, and sometimes an example works to your satisfaction and solves exactly your problem. This is amazing, and times when you built everything from scratch are long gone, but normally you should at least understand what is going on inside a library or function like pulseIn.

In your case the problem with pulseIn is that it hangs until a pulse in the right direction happens.
You'd have to set a timeout, at least.
I never started understanding the FreqCounter library, as the problem is rather trivial in your case, once you managed to setup the hardware environment properly and run your ATmega with 0V, hehe smiley-wink

Just setup a loop without delays, which checks when 1000 millis have passed and count state changes of your identify_pin.
You don't need anything but some subtractions, additions, digitalRead(), millis() and if statements
and a few intermediate static variables for the number of millis when you started, the number of state changes, and the state during the previous loop run, to detect a change.

Edit: You need the millis() function too, of course, and perhaps a few more bits, but the software part is trivial, believe me.
« Last Edit: November 08, 2012, 09:42:21 am by michael_x » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dear Michael_x,

you are right. Just I have modified the code as following:

const int identify_pin = 7;
const int yellowLED_pin = 12;
const int redLED_pin = 11;
unsigned long duration = 200;

void setup()
{
  pinMode(identify_pin, INPUT);
  pinMode(yellowLED_pin, OUTPUT);
  pinMode(redLED_pin, OUTPUT);
}

void loop()
{
  digitalWrite(redLED_pin, LOW);
  digitalWrite(yellowLED_pin, LOW);
  delay(2000);
 
  duration = pulseIn(identify_pin, HIGH, 20000);

  if(duration <= 1)
    {
       digitalWrite(redLED_pin, HIGH);
       digitalWrite(yellowLED_pin, LOW);
       delay(2000);
    }
  else
    {
       digitalWrite(redLED_pin, LOW);
       digitalWrite(yellowLED_pin, HIGH);
       delay(2000);
    }
}

If i give the arduino DC power supply 5V, the red LED can work. If i give it a PWM(50% @ 50Hz), the yellow one can work. Unfortunately, i have no AC PSU, so only use PWM to test. The test result can proof the code can solve my problem?

Because our PCB (ATmega328P) needs firstly to identify the PSU type(AC or DC) and then with the data it can do the next corresponding things, i define 20ms (max time value, a period of PSU with 50Hz >= period of PSU 60Hz) for timeout, that is, in one period can find, there is a pulse or no pulse.

Do you have any Suggestion to improve codes? Do I need to consider some what parameters or situation?
Logged


mfg

Godspeer

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In PWM-Test, the code "unsigned long duration = 200;" is changed "unsigned long duration;".

dhenry, pls, can we be friends? I understand really the project. "AC 0V working" is bullshit, i know. sorry for wrong writing. If 0V, it's sure no work. We wanna set a mini limit of working AC PSU, but it's the late thing.

Anyway, thanks for your Info
Logged


mfg

Godspeer

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 272
Posts: 25433
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
dhenry, pls, can we be friends?
You will be the first then.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is a compliment or laugh at?

Hello, Grumpy_Mike
can you help me to check the program and give some advices?

another question:
Just i make a simple test. code is:

#define PWM_Sum 1000

const int redLED_1_pin = 12;
const int redLED_2_pin = 13;

int tmp_state = 0;

void setup()
{
  pinMode(redLED_1_pin, OUTPUT);
  pinMode(redLED_2_pin, OUTPUT);
}



void loop()
{
       tmp_state = 1000;
       PWM_generator(tmp_state, PWM_Sum);
       digitalWrite(redLED_2_pin, HIGH);
}


void PWM_generator(int high_state, int sum)
{
  digitalWrite(redLED_1_pin, HIGH);   
  delayMicroseconds(high_state);
  digitalWrite(redLED_1_pin, LOW);
  delayMicroseconds(sum - high_state);
}

Why redLED_2 is quite bright and redLED_1 is very dark, but if I give tmp_state = 999, redLED_1 becomes very bright ? 
Logged


mfg

Godspeer

UK
Offline Offline
Edison Member
*
Karma: 41
Posts: 2176
What a host of balls she had seen: gaity, the brass buttons...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The first thing that delayMicroseconds() does is subtract one from the number of microseconds requested.

Thus, 0 (1000 - 1000) instantly becomes very huge (0xFFFFFFFF).

That's a massive delay.
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 272
Posts: 25433
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Why are you generating PWM like that?
Why not use the built in PWM generator?

If you have to do it by hand then you should not use delays but the "blink without delay" method as you stand a chance of doing something else as well as generating PWM.
Logged

UK
Offline Offline
Edison Member
*
Karma: 41
Posts: 2176
What a host of balls she had seen: gaity, the brass buttons...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Simple 8-bit PWM generator - can be expanded for many many many pins:

Code:
const int pin1 = 7;
const int pin2 = 8;
// ...

unsigned char pwm1 = 100;
unsigned char pwm2 = 200;
// ...

void setup()
{
  pinMode(pin1,OUTPUT);
  pinMode(pin2,OUTPUT);
  // ...
}

void loop()
{
  static unsigned char duty = 0;

  if(duty == 0)
  {
    digitalWrite(pin1,HIGH);
    digitalWrite(pin2,HIGH);
  }

  if(duty == pwm1)
    digitalWrite(pin1,LOW);

  if(duty == pwm2)
    digitalWrite(pin2,LOW);

  // ...

  duty++;
}
Logged


Germany
Offline Offline
Edison Member
*
Karma: 27
Posts: 1486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Majenko,

I understand a pwm_n = 127 sets a 50% duty.
All pins have the same PWM frequency.
Why are you generating PWM like that?
Why not use the built in PWM generator?

If you have to do it by hand then you should not use delays but the "blink without delay" method as you stand a chance of doing something else as well as generating PWM.
Where do you set the PWM frequency ?
Whithout using a delay ... that is the enhancement required for godspeer's approach.
Logged

UK
Offline Offline
Edison Member
*
Karma: 41
Posts: 2176
What a host of balls she had seen: gaity, the brass buttons...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Majenko,

I understand a pwm_n = 127 sets a 50% duty.
All pins have the same PWM frequency.
Why are you generating PWM like that?
Why not use the built in PWM generator?

If you have to do it by hand then you should not use delays but the "blink without delay" method as you stand a chance of doing something else as well as generating PWM.
Where do you set the PWM frequency ?
Whithout using a delay ... that is the enhancement required for godspeer's approach.


With my system, 2 options:

1. Instead of doing it in "loop", do it in a function attatched to a timer.
2. Use other variables to scale the counting of duty.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot guys!

Pls can you also check my first program to identify the PSU type(AC or DC) ? (use pulseIn()) 

If you have to do it by hand then you should not use delays but the "blink without delay" method as you stand a chance of doing something else as well as generating PWM.
 

Grumpy_Mike, you are right. Actually i need PWM with a frequency of a few kilohertz and also do something else. How to implement that, can u show me the codes?
Logged


mfg

Godspeer

Idaho, US
Offline Offline
Jr. Member
**
Karma: 5
Posts: 71
Special User
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In this forum, before I asked a question, I must explain you the entire complex project ?
Yes, the members on this forum prefer to know the details of the entire complex project. Without that information, they must make assumptions, which can be incorrect, and thus result in bad advice. So, refusing to help you until they know the details is actually doing you a favor. smiley

Also, it's often the case that a different but easier/better/cheaper approach can be suggested... but without the details, nobody can determine that.

Quote
I want to know only, how to program in arduino with using ATmega328P can identify AC power supply or DC power supply input.
This is heavily dependent on hardware. In order to know what code you need to write, we need to know exactly what hardware you intend to use -- and if you don't know what hardware to use, we need to know the details of your entire complex project so we can recommend the right hardware. smiley-wink
Logged

Pages: 1 [2]   Go Up
Print
 
Jump to: