Basically I am controling a ampere metre. I am using an transistor (came with Uno Starter kit) to charge a capacitator, that capacitator is emptied trough large resistors trough the apere metre. The problem is that the arduino PWM library was too low resolution and always managed to fully charge the capacitator instantly. I am using code down below.
The ampere metre goes from 0% to 100% with a values of 0 until 4300. But if I linearily increase a value the aperemetre value grows logarithmically, the map function did not help other than reducing the resolution.
So I've got two problems:
How to control the ampere metre dial with linear scale instead of logarithmic?
How to "background" the process of charging the capacitator, like Arduino's PWM function? Currently any other code throws the dial to 0.
digitalWrite(led, HIGH);
if (a > 0) {
delayMicroseconds(a);
digitalWrite(led, LOW);
delayMicroseconds(10000 - a);
}
As English is not my first language I really hope I was clear enough, if anything is unclear, please let me know.
jremington:
Please describe the external circuitry: resistors, capacitors, resistance of the meter movement and the full scale meter current.
Arduino Nano is switching an BC547B trough a 220 ohm resistor. E on the transistor is connected to ground, C is connected to the ampere metre trough 2*1Kohm and one 2Kohm resistor in parallel. The C is also connected to a 2200uF 6.3V cap to the 5V. Meter goes from 0mA to 10mA, it is an old analogue one. The meters internal resistance is 8.4 ohms.
This circuit most likely is not the right one, but this was all I could come up with as an beginner. If you can suggest me something better, let me know.
int led = 6; // the pin that the LED is attached to
int a = 3000;
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
Serial.begin(115200);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH);
if (a > 0) {
digitalWrite(led, LOW);
delayMicroseconds(a);
delayMicroseconds(10000 - a);
}
}
10 mA (full scale meter deflection) is OK for the port pin to supply directly, so try something like the attached simple RC filter. The current through the meter is linearly proportional to the average voltage, hence linearly to the PWM on time. The circuit has a response time to changes in the PWM value of about 0.1 seconds.
Avamander:
...
But if I linearily increase a value the aperemetre value grows logarithmically, the map function did not help other than reducing the resolution....
The schematic, although it does not matter much. My questions are software related.
I think that you are wrong to assume that it is a software problem.
I'm sure that it is the capacitor causing the problem.
It will charge up quickly from the PWM pulses, but will take much longer to discharge through the resistors and meter. (The time constant of the capacitor and the resistors is around 800ms.)
I think you need to remove the capacitor completely, or connect it in a different position.
If it was just connected across the meter, then it would filter the PWM signal, and give a more linear response.
I rearranged the circuit as the schematic shows and it now works, exept when the direction changes it jumps to the opposite end for a moment. During any other value it moves smoothly.
int ampere = 6;
unsigned long int last;
bool directionn;
int value = 1;
void setup() {
// declare pin 9 to be an output:
pinMode(ampere, OUTPUT);
Serial.begin(115200);
}
void loop() {
analogWrite(ampere, value);
if (millis() - last > 250) {
if (directionn == 1) {
value++;
} else {
value--;
}
if (value > 255) {
directionn = 0;
} else if (value < 0) {
directionn = 1;
}
Serial.println(value);
last = millis();
}
}
You are not changing direction until you go outside that range.
It is no surprise that it jumps when you send illegal values to the analogWrite() function
try changing:
if (value > 255) {
directionn = 0;
} else if (value < 0) {
directionn = 1;
to:
if (value > 254) {
directionn = 0;
} else if (value < 1) {
directionn = 1;
JohnLincoln:
Valid values for analogWrite() are 0 to 255.
You are not changing direction until you go outside that range.
It is no surprise that it jumps when you send illegal values to the analogWrite() function