Follow along with the video below to see how to install our site as a web app on your home screen.
Huomio: This feature may not be available in some browsers.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Create a new LiquidCrystal_I2C display object with the correct I2C address and display size
// Define the pins
const int currentPin = A0; //information about current
const int motorPin = 7; //motor running pin, HIGH = motor running, TEST purpose LOW
const int pwmPin = 9; //PWM output pin
const int relayPin = 3; //Relay control pin
float voltageFactor = 5.0 / 1023.0; //Factor to convert ADC reading to voltage
float currentFactor = 80 / 4.8351848; //4.8351848 volts = 80 amps, factor to convert voltage to current
float current; //store current value
const int N = 10; //number of readings to average
int readings[N]; //array to store the readings
int motorStatus; //0=stopped, 1=starting, 2=running, 3=stopped but did run
unsigned long lastTime = 0; //timer to measure engine sensor input time for starting
void setup() {
Serial.begin(9600); // Start the serial communication
// Initialize the LCD here
// Give the screen time to boot
delay(1500);
lcd.begin(16, 2);
lcd.backlight();
lcd.clear();
// Change timers on pins to change PWM freq to 122 Hz
// Pins D9 and D10 - 122 Hz
TCCR1A = 0b00000001; // 8bit
TCCR1B = 0b00000100; // x256 phase correct
// Make pins output/input
pinMode(currentPin, INPUT); //Information on charging current
pinMode(motorPin, INPUT_PULLUP); //For real use, delete _PULLUP (it is for test purpose, pullup resistor)
pinMode(pwmPin, OUTPUT); //Charger pwm output
pinMode(relayPin, OUTPUT); //Ignition relay pin
}
void motorRunning() { //engine running function
if (digitalRead(motorPin) == HIGH && motorStatus == 0) {
if (millis() - lastTime >= 6000) { //wait at least 6 seconds before ramping up pwn and so start charging
motorStatus = 1;
}
} else if (motorStatus == 0) {
lastTime = millis();
lcd.setCursor(0, 0); //On lcd print Finnish to start the engine
lcd.print("K");
lcd.print((char)0xe1);
lcd.print("ynnist");
lcd.print((char)0xe1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("moottori");
}
}
void rampUp() { //rampup pwm
// Ramp pwm up
if (motorStatus == 1) {
analogWrite(pwmPin, 13);
delay(1000);
analogWrite(pwmPin, 48);
delay(1000);
analogWrite(pwmPin, 83);
delay(1000);
analogWrite(pwmPin, 118);
delay(1000);
analogWrite(pwmPin, 153); //Duty Cycle at 60 percent
motorStatus = 2;
}
}
void shutDown() { //engine shutdown, execute relay
// If the charging current drops below five amperes
// start the shutdown function and turn off the relay for 15 seconds
if (current < 5 && motorStatus == 2) {
digitalWrite(relayPin, LOW);
lcd.setCursor(0, 0);
lcd.print("Sammutus... ");
//motorStatus = 3;
} else {
digitalWrite(relayPin, HIGH); //else, keep relay on
}
}
void motorDidRun() { //engine has stopped after it was running, this function is not needed at the time
if (motorStatus == 3) {
lcd.setCursor(0, 0);
lcd.print("K");
lcd.print((char)0xe1);
lcd.print("ynnist");
lcd.print((char)0xe1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("uudelleen");
}
}
void loop() {
//calculate current from shunt reading
// Calculate the charging current from the average and display it on the LCD screen.
// take N readings and store them in the array
for (int i = 0; i < N; i++) {
readings[i] = analogRead(currentPin);
delay(10); // wait for 10 milliseconds between readings
}
// calculate the average of the N readings
float sum = 0;
for (int i = 0; i < N; i++) {
sum += readings[i];
}
float average = sum / N;
float voltage = average * voltageFactor; // Convert ADC reading to voltage
current = voltage * currentFactor; // Convert voltage to current
lcd.setCursor(0, 0);
lcd.print("Latausvirta:");
lcd.setCursor(0, 1);
lcd.print((int)current);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" A");
lcd.setCursor(5, 1);
lcd.print(" ");
motorRunning();
rampUp();
shutDown();
motorDidRun();
Serial.println("Motor status: ");
Serial.println((int)motorStatus);
Serial.println("Current: ");
Serial.println((float)current);
}
No niin, sain tämänkin koodin nyt toimimaan. On vaan aika "ruma" koodi, kun virran ulkopuoliset näytöt tulostetaan virtanäytön päälle ja näyttö värisee. No, kuitenkin nyt toimii.
Sain tuon virran laskennan toimimaan, kun laitoin ko. funktion sellaisenaan loopiin. Lisäksi poistin tilan 3. Moottorin sammuminen on huomioitu (rumasti) niin, että käyttäjä kytkee käyttövirran pois ja vääntää kytkimen uudelleen päälle.
C++:#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // Create a new LiquidCrystal_I2C display object with the correct I2C address and display size // Define the pins const int currentPin = A0; //information about current const int motorPin = 7; //motor running pin, HIGH = motor running, TEST purpose LOW const int pwmPin = 9; //PWM output pin const int relayPin = 3; //Relay control pin float voltageFactor = 5.0 / 1023.0; //Factor to convert ADC reading to voltage float currentFactor = 80 / 4.8351848; //4.8351848 volts = 80 amps, factor to convert voltage to current float current; //store current value const int N = 10; //number of readings to average int readings[N]; //array to store the readings int motorStatus; //0=stopped, 1=starting, 2=running, 3=stopped but did run unsigned long lastTime = 0; //timer to measure engine sensor input time for starting void setup() { Serial.begin(9600); // Start the serial communication // Initialize the LCD here // Give the screen time to boot delay(1500); lcd.begin(16, 2); lcd.backlight(); lcd.clear(); // Change timers on pins to change PWM freq to 122 Hz // Pins D9 and D10 - 122 Hz TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000100; // x256 phase correct // Make pins output/input pinMode(currentPin, INPUT); //Information on charging current pinMode(motorPin, INPUT_PULLUP); //For real use, delete _PULLUP (it is for test purpose, pullup resistor) pinMode(pwmPin, OUTPUT); //Charger pwm output pinMode(relayPin, OUTPUT); //Ignition relay pin } void motorRunning() { //engine running function if (digitalRead(motorPin) == HIGH && motorStatus == 0) { if (millis() - lastTime >= 6000) { //wait at least 6 seconds before ramping up pwn and so start charging motorStatus = 1; } } else if (motorStatus == 0) { lastTime = millis(); lcd.setCursor(0, 0); //On lcd print Finnish to start the engine lcd.print("K"); lcd.print((char)0xe1); lcd.print("ynnist"); lcd.print((char)0xe1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("moottori"); } } void rampUp() { //rampup pwm // Ramp pwm up if (motorStatus == 1) { analogWrite(pwmPin, 13); delay(1000); analogWrite(pwmPin, 48); delay(1000); analogWrite(pwmPin, 83); delay(1000); analogWrite(pwmPin, 118); delay(1000); analogWrite(pwmPin, 153); //Duty Cycle at 60 percent motorStatus = 2; } } void shutDown() { //engine shutdown, execute relay // If the charging current drops below five amperes // start the shutdown function and turn off the relay for 15 seconds if (current < 5 && motorStatus == 2) { digitalWrite(relayPin, LOW); lcd.setCursor(0, 0); lcd.print("Sammutus... "); //motorStatus = 3; } else { digitalWrite(relayPin, HIGH); //else, keep relay on } } void motorDidRun() { //engine has stopped after it was running, this function is not needed at the time if (motorStatus == 3) { lcd.setCursor(0, 0); lcd.print("K"); lcd.print((char)0xe1); lcd.print("ynnist"); lcd.print((char)0xe1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("uudelleen"); } } void loop() { //calculate current from shunt reading // Calculate the charging current from the average and display it on the LCD screen. // take N readings and store them in the array for (int i = 0; i < N; i++) { readings[i] = analogRead(currentPin); delay(10); // wait for 10 milliseconds between readings } // calculate the average of the N readings float sum = 0; for (int i = 0; i < N; i++) { sum += readings[i]; } float average = sum / N; float voltage = average * voltageFactor; // Convert ADC reading to voltage current = voltage * currentFactor; // Convert voltage to current lcd.setCursor(0, 0); lcd.print("Latausvirta:"); lcd.setCursor(0, 1); lcd.print((int)current); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" A"); lcd.setCursor(5, 1); lcd.print(" "); motorRunning(); rampUp(); shutDown(); motorDidRun(); Serial.println("Motor status: "); Serial.println((int)motorStatus); Serial.println("Current: "); Serial.println((float)current); }
=!
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Create a new LiquidCrystal_I2C display object with the correct I2C address and display size
// Define the pins
const int currentPin = A0; //information about current
const int motorPin = 7; //motor running pin, HIGH = motor running, TEST purpose LOW
const int pwmPin = 9; //PWM output pin
const int relayPin = 3; //Relay control pin
float voltageFactor = 5.0 / 1023.0; //Factor to convert ADC reading to voltage
float currentFactor = 80 / 4.8351848; //4.8351848 volts = 80 amps, factor to convert voltage to current
float current; //store current value
const int N = 10; //number of readings to average
int readings[N]; //array to store the readings
int motorStatus; //0=stopped, 1=starting, 2=running, 3=stopped but did run, on status 3, just switch off and on again to go back 0
unsigned long lastTime = 0; //timer to measure engine sensor input time for starting
void setup() {
Serial.begin(9600); // Start the serial communication
// Initialize the LCD here
// Give the screen time to boot
delay(1500);
lcd.begin(16, 2);
lcd.backlight();
lcd.clear();
// Change timers on pins to change PWM freq to 122 Hz
// Pins D9 and D10 - 122 Hz
TCCR1A = 0b00000001; // 8bit
TCCR1B = 0b00000100; // x256 phase correct
// Make pins output/input
pinMode(currentPin, INPUT); //Information on charging current
pinMode(motorPin, INPUT_PULLUP); //For real use, delete _PULLUP (it is for test purpose, pullup resistor)
pinMode(pwmPin, OUTPUT); //Charger pwm output
pinMode(relayPin, OUTPUT); //Ignition relay pin
}
void motorRunning() { //engine running function
if (digitalRead(motorPin) == HIGH && motorStatus == 0) {
if (millis() - lastTime >= 6000) { //wait at least 6 seconds before ramping up pwn and so start charging
motorStatus = 1;
}
} else if (motorStatus == 0) {
lastTime = millis();
lcd.setCursor(0, 0); //On lcd print Finnish to start the engine
lcd.print("K");
lcd.print((char)0xe1);
lcd.print("ynnist");
lcd.print((char)0xe1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("moottori");
}
}
void rampUp() { //rampup pwm
// Ramp pwm up
if (motorStatus == 1) {
analogWrite(pwmPin, 13);
delay(1000);
analogWrite(pwmPin, 48);
delay(1000);
analogWrite(pwmPin, 83);
delay(1000);
analogWrite(pwmPin, 118);
delay(1000);
analogWrite(pwmPin, 153); //Duty Cycle at 60 percent
motorStatus = 2;
}
}
void shutDown() { //engine shutdown, execute relay
// If the charging current drops below five amperes
// start the shutdown function and turn off the relay for 15 seconds
if (current < 5 && motorStatus == 2) {
digitalWrite(relayPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sammutus");
motorStatus = 3;
} else {
digitalWrite(relayPin, HIGH); //else, keep relay on
}
}
void showCurrent() { //show current on lcd only when normal running state
if (motorStatus == 2) {
lcd.setCursor(0, 0);
lcd.print("Latausvirta:");
lcd.setCursor(0, 1);
lcd.print((int)current);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" A");
lcd.setCursor(5, 1);
lcd.print(" ");
}
}
void loop() {
//calculate current from shunt reading
// Calculate the charging current from the average and display it on the LCD screen.
// take N readings and store them in the array
for (int i = 0; i < N; i++) {
readings[i] = analogRead(currentPin);
delay(10); // wait for 10 milliseconds between readings
}
// calculate the average of the N readings
float sum = 0;
for (int i = 0; i < N; i++) {
sum += readings[i];
}
float average = sum / N;
float voltage = average * voltageFactor; // Convert ADC reading to voltage
current = voltage * currentFactor; // Convert voltage to current
motorRunning();
rampUp();
shutDown();
showCurrent();
Serial.println("Motor status: ");
Serial.println((int)motorStatus);
Serial.println("Current: ");
Serial.println((float)current);
}
@ississ , joo, iso alumiinipohjalevy on ruuveilla kiinni kotelossa. Kaikki kortit on myös ruuveilla kiinni tuossa pellissä. Ei ehkä erotu kuvasta! Tärinäanturi on myös ruuvilla kiinni + kuumaliima, jotta ei pyöri miten sattuu. Lisäksi ajattelen, että ehkä lopulliseen hässäkkään varmuuden vuoksi pitää vielä laittaa pellin taustapuolelle mutterit, vaikka pellissä kierre onkin. Toinen vaihtoehto on laittaa kierrelukitetta.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Create a new LiquidCrystal_I2C display object with the correct I2C address and display size
// Define the pins
const int currentPin = A0; //information about current
const int voltagePin = A2; //information about voltage
const int motorPin = 7; //motor running pin, HIGH = motor running, TEST purpose LOW
const int pwmPin = 9; //PWM output pin
const int relayPin = 3; //Relay control pin
float voltageFactor = 5.0 / 1023.0; //Factor to convert ADC reading to voltage
float currentFactor = 80 / 4.8351848; //4.8351848 volts = 80 amps, factor to convert voltage to current
float sensVfactor = 20 / 4.8351848; //4.8351848 volts = 20 volts, factor to convert high voltage to 0-5 V
float current; //store current value
float sensVoltage; //store sensed voltage
const int N = 10; //number of current readings to average
const int Y = 10; //number of sensed voltage readings to average
int readings[N]; //array to store the current readings
int readingsV[Y]; //array to store the sensed voltage readings
int motorStatus; //0=stopped, 1=starting, 2=running, 3=stopped but did run, on status 3, just switch off and on again to go back 0
int lcdStep; //0=current display, 1=voltage display
unsigned long lastTime = 0; //timer to measure engine sensor input time for starting
unsigned long lastDisp = 0; //timer to measure display step time for changing lcd values
unsigned long interval = 2000; //how often to swap lcd between volts and amps
void setup() {
Serial.begin(9600); // Start the serial communication
// Initialize the LCD here
// Give the screen time to boot
delay(1500);
lcd.begin(16, 2);
lcd.backlight();
lcd.clear();
// Change timers on pins to change PWM freq to 122 Hz
// Pins D9 and D10 - 122 Hz
TCCR1A = 0b00000001; // 8bit
TCCR1B = 0b00000100; // x256 phase correct
// Make pins output/input
pinMode(currentPin, INPUT); //Information on charging current
pinMode(voltagePin, INPUT); //information on voltage
pinMode(motorPin, INPUT_PULLUP); //For real use, delete _PULLUP (it is for test purpose, pullup resistor)
pinMode(pwmPin, OUTPUT); //Charger pwm output
pinMode(relayPin, OUTPUT); //Ignition relay pin
}
void motorRunning() { //engine running function
if (digitalRead(motorPin) == HIGH && motorStatus == 0) {
if (millis() - lastTime >= 6000) { //wait at least 6 seconds before ramping up pwn and so start charging
motorStatus = 1;
}
} else if (motorStatus == 0) {
lastTime = millis();
lcd.setCursor(0, 0); //On lcd print Finnish to start the engine
lcd.print("K");
lcd.print((char)0xe1);
lcd.print("ynnist");
lcd.print((char)0xe1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("moottori");
}
}
void rampUp() { //rampup pwm
// Ramp pwm up
if (motorStatus == 1) {
analogWrite(pwmPin, 13);
delay(1000);
analogWrite(pwmPin, 48);
delay(1000);
analogWrite(pwmPin, 83);
delay(1000);
analogWrite(pwmPin, 118);
delay(1000);
analogWrite(pwmPin, 153); //Duty Cycle at 60 percent
motorStatus = 2;
}
}
void shutDown() { //engine shutdown, execute relay
// If the charging current drops below five amperes
// start the shutdown function and turn off the relay for 15 seconds
if (current < 5 && motorStatus == 2) {
digitalWrite(relayPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sammutus");
motorStatus = 3;
} else {
digitalWrite(relayPin, HIGH); //else, keep relay on
}
}
void showCurrent() { //show current on lcd only when normal running state
if (motorStatus == 2) {
unsigned long currentMillis = millis();
if (currentMillis - lastDisp >= interval) {
lcd.setCursor(0, 0);
lcd.print("Latausvirta:");
lcd.setCursor(0, 1);
lcd.print((int)current);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" A");
lcd.setCursor(5, 1);
lcd.print(" ");
lcdStep = 0;
} else {
currentMillis = millis();
lcd.setCursor(0, 0);
lcd.print("Latausj");
lcd.print((char)0xe1);
lcd.print("nnite:");
lcd.setCursor(0, 1);
lcd.print((int)sensVoltage);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" V");
lcd.setCursor(5, 1);
lcd.print(" ");
lcdStep = 1;
}
}
}
void loop() {
//calculate current from shunt reading
// Calculate the charging current from the average and display it on the LCD screen.
// take N readings and store them in the array
for (int i = 0; i < N; i++) {
readings[i] = analogRead(currentPin);
delay(10); // wait for 10 milliseconds between readings
}
// calculate the average of the N readings
float sum = 0;
for (int i = 0; i < N; i++) {
sum += readings[i];
}
float average = sum / N;
float voltage = average * voltageFactor; // Convert ADC reading to voltage
current = voltage * currentFactor; // Convert voltage to current
//calculate high voltage from voltage divider input
// Calculate the charging voltage from the average and display it on the LCD screen.
// take Y readings and store them in the array
for (int j = 0; j < Y; j++) {
readingsV[j] = analogRead(voltagePin);
delay(10); // wait for 10 milliseconds between readings
}
// calculate the average of the N readings
float sumV = 0;
for (int j = 0; j < Y; j++) {
sumV += readingsV[j];
}
float averageV = sumV / Y;
float voltageV = averageV * voltageFactor; // Convert ADC reading to voltage
sensVoltage = voltageV * sensVfactor; // Convert voltage to real voltage
motorRunning();
rampUp();
shutDown();
showCurrent();
Serial.println("Motor status: ");
Serial.println((int)motorStatus);
Serial.println("Jannite: ");
Serial.println((float)sensVoltage);
Serial.println("Virta: ");
Serial.println((float)current);
}
Laitoin volttien laskennan tuohon virranmittauksen jatkoksi samalla tavalla. Se todennäköisesti kyllä toimii, mutta jotenkin se nappaa nyt jotain tuosta virranlaskennasta, koska se reagoi tuohon virtatulon pinniin liitettyyn potikkaan. Kun volttituloon tarkoitettuun pinniin ei ole kytketty mitään, tuloksena on noin 19 V, kun virtaa simuloiva potikka on täysillä (noin 82 ampeeria). Potikkaa pyöritellessä myös voltit laskee.
Tässä on varmaan joku yksinkertainen kämmi, jota en nyt huomaa. Tai sitten noita funktioita (jännite ja virta) ei voi laittaa noin peräkkäin, vaan ne pitäisi jotenkin erottaa. Loopiin ne mielestäni kuitenkin tulisi laittaa, jotta niitä lasketaan aina ja koko ajan, mutta jotain erottavaa noista voi välistä puuttua.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Create a new LiquidCrystal_I2C display object with the correct I2C address and display size
// Define the pins
const int currentPin = A0; //information about current
const int voltagePin = A2; //information about voltage
const int motorPin = 7; //motor running pin, HIGH = motor running, TEST purpose LOW
const int pwmPin = 9; //PWM output pin
const int relayPin = 3; //Relay control pin
float voltageFactor = 5.0 / 1023.0; //Factor to convert ADC reading to voltage
float currentFactor = 80 / 4.8351848; //4.8351848 volts = 80 amps, factor to convert voltage to current
float sensVfactor = 20 / 4.8351848; //4.8351848 volts = 20 volts, factor to convert high voltage to 0-5 V
float current; //store current value
float sensVoltage; //store sensed voltage
const int N = 10; //number of current readings to average
const int Y = 10; //number of sensed voltage readings to average
int readings[N]; //array to store the current readings
int readingsV[Y]; //array to store the sensed voltage readings
int motorStatus; //0=stopped, 1=starting, 2=running, 3=stopped but did run, on status 3, just switch off and on again to go back 0
int lcdStep; //0=current display, 1=voltage display
unsigned long lastTime = 0; //timer to measure engine sensor input time for starting
unsigned long lastDisp = 0; //timer to measure display step time for changing lcd values
int interval = 3000; //how often to swap lcd between volts and amps
void setup() {
Serial.begin(9600); // Start the serial communication
// Initialize the LCD here
// Give the screen time to boot
delay(1500);
lcd.begin(16, 2);
lcd.backlight();
lcd.clear();
// Change timers on pins to change PWM freq to 122 Hz
// Pins D9 and D10 - 122 Hz
TCCR1A = 0b00000001; // 8bit
TCCR1B = 0b00000100; // x256 phase correct
// Make pins output/input
pinMode(currentPin, INPUT); //Information on charging current
pinMode(voltagePin, INPUT_PULLUP); //information on voltage, for real use, delete _PULLUP
pinMode(motorPin, INPUT_PULLUP); //Vibration sensor in, for motor running detect, for real use, delete _PULLUP (it is for test purpose, pullup resistor)
pinMode(pwmPin, OUTPUT); //Charger pwm output
pinMode(relayPin, OUTPUT); //Ignition relay pin
}
void motorRunning() { //engine running function
if (digitalRead(motorPin) == HIGH && motorStatus == 0) {
if (millis() - lastTime >= 6000) { //wait at least 6 seconds before ramping up pwn and so start charging
motorStatus = 1;
}
} else if (motorStatus == 0) {
lastTime = millis();
lcd.setCursor(0, 0); //On lcd print Finnish to start the engine
lcd.print("K");
lcd.print((char)0xe1);
lcd.print("ynnist");
lcd.print((char)0xe1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("moottori");
}
}
void rampUp() { //rampup pwm
// Ramp pwm up
if (motorStatus == 1) {
analogWrite(pwmPin, 13);
delay(1000);
analogWrite(pwmPin, 48);
delay(1000);
analogWrite(pwmPin, 83);
delay(1000);
analogWrite(pwmPin, 118);
delay(1000);
analogWrite(pwmPin, 153); //Duty Cycle at 60 percent
motorStatus = 2;
}
}
void shutDown() { //engine shutdown, execute relay
// If the charging current drops below five amperes
// start the shutdown function and turn off the relay for 15 seconds
if (current < 5 && motorStatus == 2) {
digitalWrite(relayPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sammutus");
motorStatus = 3;
} else {
digitalWrite(relayPin, HIGH); //else, keep relay on
}
}
void showCurrent() { //show current and voltage on lcd only when normal running state
if (motorStatus == 2) {
if (millis() >= lastDisp + interval && lcdStep == 0) {
lastDisp += interval;
lcd.setCursor(0, 0);
lcd.print("Latausvirta: ");
lcd.setCursor(0, 1);
lcd.print((int)current);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" A");
lcdStep = 1;
} else if (millis() >= lastDisp + interval && lcdStep == 1) {
lastDisp += interval;
lcd.setCursor(0, 0);
lcd.print("Latausj");
lcd.print((char)0xe1);
lcd.print("nnite:");
lcd.setCursor(0, 1);
lcd.print((int)sensVoltage);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" V");
lcd.setCursor(5, 1);
lcd.print(" ");
lcdStep = 0;
}
}
}
void loop() {
//calculate current from shunt reading
// Calculate the charging current from the average and display it on the LCD screen.
// take N readings and store them in the array
for (int i = 0; i < N; i++) {
readings[i] = analogRead(currentPin);
delay(10); // wait for 10 milliseconds between readings
}
// calculate the average of the N readings
float sum = 0;
for (int i = 0; i < N; i++) {
sum += readings[i];
}
float average = sum / N;
float voltage = average * voltageFactor; // Convert ADC reading to voltage
current = voltage * currentFactor; // Convert voltage to current
//calculate high voltage from voltage divider input
// Calculate the charging voltage from the average and display it on the LCD screen.
// take Y readings and store them in the array
for (int j = 0; j < Y; j++) {
readingsV[j] = analogRead(voltagePin);
delay(10); // wait for 10 milliseconds between readings
}
// calculate the average of the N readings
float sumV = 0;
for (int j = 0; j < Y; j++) {
sumV += readingsV[j];
}
float averageV = sumV / Y;
float voltageV = averageV * voltageFactor; // Convert ADC reading to voltage
sensVoltage = voltageV * sensVfactor; // Convert voltage to real voltage
motorRunning();
rampUp();
shutDown();
showCurrent();
Serial.print("Lcdstep: ");
Serial.print((int)lcdStep);
Serial.println();
Serial.print("Jannite: ");
Serial.print((float)sensVoltage);
Serial.println();
Serial.print("Virta: ");
Serial.print((float)current);
Serial.println();
}
Läppäsin itseäni otsalle, kun kyllähän tuo on varmaan legendaarisimpia "ongelmia" jos määritelty portti jätetään avoimeksi.
Kokeeksi otin potikan pois myös virtapinnistä ja myös tuo virta-arvo jäi samalla tavalla kellumaan. Eiköhän tuokin volttimittaus toimi, kunhan siihen on oikea syöte. Voiko tätä muuten turvallisesti testata ulkoisella virtalähteellä, eli syöttää vaikkapa 3 volttia tuohon pinniin maata vasten? Kaiken järjen mukaan voi.
@ississ kertoi mittausloopien yhdistämisestä. Varmasti näin olisi viisainta tehdä. Tästä en vielä oikein ymmärrä mitään. Kuvittelen, että tuossa jotain lisätään jonnekin kuvitteelliseen (?) taulukkoon, ja sieltä lasketaan aina se keskiarvo, jota vasta käytetään lopullisen arvon laskennassa. Tuo koodi on tekoälyn tekemä, ja apinoin tuon virtamittauksen kaveriksi samalla kaavalla volttien mittaamiseen vastaavan pätkän.
Ehkä eniten jumppaa tarvii ajatus, että käytettäisiin samaa summaa uudelleen. Ymmärrän niin, että laskettaisiin keskiarvot ennen kuin yksittäisiä mittauksia (10 x 2 kpl) tallennetaan sinne taulukkoon?
// NYKYISESTÄ KOODISTA:
// loop 1: mittaa virrat taulukkoon (10 arvoa)
for (int i = 0; i < N; i++) {
readings[i] = analogRead(currentPin);
delay(10);
}
// loop 2: taulukon arvojen keskiarvo
float sum = 0;
for (int i = 0; i < N; i++) {
sum += readings[i];
}
float average = sum / N;
float voltage = average * voltageFactor; // Convert ADC reading to voltage
current = voltage * currentFactor; // Convert voltage to current
// loop 3: mittaa jännitteet eri taulukkoon (voisi olla samakin)
for (int j = 0; j < Y; j++) {
readingsV[j] = analogRead(voltagePin);
delay(10); // wait for 10 milliseconds between readings
}
// loop 4 : jännitemittausten keskiarvo
float sumV = 0;
for (int j = 0; j < Y; j++) {
sumV += readingsV[j];
}
float averageV = sumV / Y;
float voltageV = averageV * voltageFactor;
sensVoltage = voltageV * sensVfactor;
// KUMPIKIN YHDELLÄ LOOPILLA (EN TESTANNUT):
// Mittausten lukumäärä
#define NUMBER_OF_MEASURES 10
// Virta
float sum = 0.0;
// Mitataan virta 10 kertaa ja lasketaan suoraan summaan
for (int i = 0; i < NUMBER_OF_MEASURES ; i++) {
sum += analogRead(currentPin);
delay(10);
}
// Lopuksi jako määrällä => keskiarvo ja kertoimet -> reaalimaailman arvo
current = (sum / (float)NUMBER_OF_MEASURES) * voltageFactor * currentFactor;
// Jännite
sum = 0.0; // Uusiokäytetään sum- muuttuja koska laskettu virta tallennettiin eri muuttujaan, sum arvolla ei tehdä enää mitään.
// HUOM: int i on määritetty vain for() sisällä, voi käyttää samaa eikä sekoita looppeja
for (int i = 0; i < NUMBER_OF_MEASURES; i++) {
sum += analogRead(voltagePin);
delay(10);
}
voltage = (sum / (float) NUMBER_OF_MEASURES) * voltageFactor * sensVFactor;
// Mittausten lukumäärä
#define NUMBER_OF_MEASURES 10
// Virta
float sumC = 0.0;
float sumV = 0.0;
for (int i = 0; i < NUMBER_OF_MEASURES; i++) {
sumC += analogRead(currentPin);
delay(5);
sumV += analogRead(voltagePin);
delay(5);
}
current = (sumC / (float)NUMBER_OF_MEASURES) * voltageFactor * currentFactor;
sensVoltage = (sumV / (float) NUMBER_OF_MEASURES) * voltageFactor * sensVFactor;
Virtalähteeltä 12 V - 5 V tulee yleismittarilla mitattuna USB-liittimestä maata vasten oikea, 5 V, mutta kun se liitetään Arduinoon, laskee jännite 3 volttiin, eikä toimi. Kyseessä oli tämän tyyppinen: https://www.elektroniikkaosat.com/c-95/ ... oja-i.html Nämähän voi olla kiina-laatua, joten vika voi olla tässä virtalähteessä. Irrallisella matkapuhelimen laturilla usb-johdon kautta toimi.
Shunttipiiriltä tulee ajoittain, jollakin käynnistyskerralla, Arduinolle kännykän laturin jännite, n. 4,7 volttia joten ampeerit näytöllä on koko ajan noin 76 ampeeria. Tämä johtunee jälleen siitä, kun johdossa ei liiku mitään, niin alkaa "kellumaan". Pitäiskö tässä olla siis _PULLUP aina käytössä? Se toki vaikuttaa sitten kalibrointiarvoon, mutta sehän ei haittaa?
Mitattuna laturin päästä, RC-pinniin menee 122 Hz:n ja 60 prosentin, mutta oskilloskoopin mielestä 5 voltin PWM. Epäilen jo oskilloskooppia, vaikka se on toiminut täydellisesti vailla ongelmia. Yleismittarilla mitattuna jännite on noin 10,6 volttia. Hyvin outoa. Laturi ei kuitenkaan lähde lataamaan. Arduinon näytön mukaan jännite on 13,66 volttia, joka on oikein, myös yleismittarilla tulee sama: karkeasti laskettuna (jännitteenjakokytkennästäni) 3,18 V / 4,7 V * 20 V ~ 13,6 V. Myös AS-pinni oli kytkettynä akkujännitteeseen.
Ennen tätä testiä, kannettuani ison akun sisälle, toimi virranmittaus koko ajan oikein, 8,3 ampeeria tuli kahdella H7-lampulla pienen kalibroinnin jälkeen. Mutta kun siis kaikki oli kytkettynä kuin lopullisessa tulee olemaan, homma ei toiminutkaan. Joku tuossa kytkennässä tai piireissä varmasti mättää. Tarkistin johdotuksen vielä useampaan kertaan.
Välttääkseni akun kantelua edes taas sisälle ja talliin, pitää yrittää sisällä testailla 12 V:n virtalähteellä tätä, hankalaa kun on vain 2 ampeerin virtalähde, niin pitää jostain metsästää ehkäpä ampeerin-puolentoista hehku tms. (virtakynnykseksi muutin koodiin nyt todella matalan 0,1 ampeeria, jotta koodi pysyy "päällä"). Tämän testin tein 100 ampeerin vapaa-ajan akulla autotallissa!
Nyt on aivot aika tavalla solmussa!
Mutta, mutta. Sehän toimi taas normaalisti taas lattialla kännykän laturilla ja 12 V:n virtalähteellä (12 voltin piiriin). Tuskin kun oskua kannattaa siis epäillä. Siis laturille meni jostain ihmeen syystä sitten 5 voltin pulssi!Elikkä kun se oli kytkettynä lopullisessa muodossaan, niin silloin ei toiminut. Shuntti on tuossa sisätestissäni vielä testaamatta, mutta tässä kuva.
Miten muuten, pitäisikö tuossa Vmax olla tuo 12 V ja Vmin 0 V?
Laitan myös vielä kytkentäkaaviot, mutta kyllä tuosta kuvastakin nähnee suurentamalla, miten on kytketty.
Tuo skoopin näyttämä saattaa johtua ihan siitä että skooppi on AC-couplingilla ja ilmeisesti skooppi on FNIRSI tai joku sen kopio joka muutenkin on vähän "epäselkeä" noiden mittausten kanssa. Mutta tosiaan signaali on reilu 12V peak-to-peak. Ja kuten jo mainittiin niin kytkentäkaavio pitäisi nähdä, tosta kuvasta ei niin paljon jaksa katsoa että varmistaisi ettei se itsessään aiheuta jotain jännää.Kuulostaa rikkinäiseltä. Jos ei toimisi toisellakaan niin sitten voisi epäillä kytkentävirhettä...
Analogitulojen kanssa AVR tulon digiosa kuuluu ottaa pois päältä (varmaan analogread sen jo tekeekin) koska se häiritsee mittausta ja silloin pullup ei ole enää vaihtoehto. Eli AVR digitaalituloa ja analogituloa ei saa sotkea keskenään, vain toinen kerrallaan.
Shuntti/mittauskytkentä pitää tehdä niin että se antaa ulos 0V jos virta on 0.
Yksi vaihtoehto pwm jännitetasolle on että tason nostopiiri ei jaksa ajaa koska kuorma on sen verran pieni. Kytkentä pitäisi nähdä, muuten voi vain arvata.
Toinen mahdollinen voisi kuitenkin olla kytkentä jos kerran lattialla toimii.
Mittasitko molemmat (5V ja 10.6V) samaan aikaan ?
Yleismittarilla pwm- signaalin mittaus ei kyllä yleensä näytä mitään järkevää.
Arvaan että skoopin 0 ei ole 0v vaan jotain muuta koska Vpp = 12.4 (= |Vmin|+|Vmax| = 4.9 + 7.5)
Tämän enempää ei voi oikein arvailla, koko systeemin kytkentä pitäisi nähdä.
Tekisin varmaan itse niin että syöttäisin arduinokortille vin kautta jännitteen eikä usb- portin kautta. Kortillahan on 5V regulaattori ja jos kortin lisäksi on vain näyttö ja jotain pientä niin se pitäisi riittää kyllä hyvin.
Jos ei koskaan kytke samaan aikaan usb- johtoa niin sitten voi syöttää suoraan 5V- liittimeen myös, arduinokortilla on vain diodit jotka erottaa eri lähteet toisistaan (usb / vin+regu).
Ei ole mitenkään harvinaista että pöydällä käytettynä akusta/hyvästä powerista kaikki toimii ja sitten virallinen asennus ei kun mukana on ehkä eri poweri, vähän pwm- häiriöitä jne.
Osa voi johtua vain johdotuksista ja/tai maadotuksen toteutustavasta.
@KanOl , ei tarvi varmasti kauheesti virtaa. Ohjaukseen vaan. Tuo virrankesto ei tietenkään tarvisi olla noin korkea. Vanha varmaan oli vaan rikki. 12 voltin piirissä kulutus oli 0,03, joka laskennallisesti olisi 5 voltin puolella noin 0,08 ampeeria. Kiinteä sen lähtöjännitteen tosiaan kannattaisi olla. Jostain Suomesta pliis! Mites tämä: Step-down-muunnin 2 A, 2,95 € - AHaa Elektroniikka
Kyllä se virtalähde oli rikki. Ei siihen kestänyt kytkeä Arduinoa pelkästäänkään, nyt laski jännite enää 1,8 volttiin!
Itse ajattelin myös noita Arduinon virransyöttömahdollisuuksia ja päädyin asiaan hieman tutustuttuani valitsemaan USB-liitännän. Niitä muita aina varoiteltiin käyttämästä. Nyt olen taas kääntymässä siihen suuntaan, että ehkä sitä uskaltaisi käyttää kuitenkin muuta reittiä syöttää kortille jännite. Viiden voltin jännite se kannattaa olla, koska sitä tarvitsevat myös muut oheiskortit.
Tässä olisi kaavio tuosta oheiskytkennästä. Ao. terminaaleista menee sitten Arduinoon, shunttiin, jne. johdot. BTW tein kaavion alun perinkin englanniksi. Enpä tiedä miksi.
Mittaa paljonko kulutus on oikeasti 5V syötöstä, tuskin tarvitsee erillistä. Kannattaa myös katsoa arduinokortin kytkentä miten se on toteutettu eikä ehkä uskoa nettijuttuja hyvästä ja huonosta...
Joka tapauksessa saa aikaan vahinkoa jos kytkee väärin, tässä sama homma.
Pwm- kytkennän transistoreilta puuttuu sulkuvastukset, siis B-E väliltä. Ilman sitä ei välttämättä sulkeudu riittävän nopeasti kuormalla. Samoin hfe pnpllä on aika pieni, nopeude vuoksi ohjaisin ehkä enemmän. 10k on ollut sopiva kytkimen ohjaus hfe tyyliin 400.
Npn kannan alasveto pitää lähdön aisoissa niin kauan kun avr käynnistyy ja lähdöt on input- tilassa. Kannattaa aina olla varma ohjauksissa.
Rakensin kytkennät uudestaan talliin, jossa iso akku on. 5 voltin johdosta mitattuna kulutus oli 0,08 ampeeria. Kortit saivat virtansa kännykän laturilla Arduinon USB-portista.
Testissä tulee tosiaan 12 voltin piiri kytkettynä Arduinon A0-navalle koko ajan noin 4,7 V, joka kääntyy noin 76 ampeeriksi. Kun 12 V kytketään pois, virta on 0,60 A (?). Kuitenkin, suoraan Vin-navoista mitattuna jännite on nolla. Virtamittaustesti irrallaan akusta on siis vieläkin tekemättä, yritän saada käsiini jostain pienempivirtaisia hehkuja, jotta voisin testata tuolla 2 ampeerin virtalähteelläni.
Muuten testillä aika jänniä tuloksia. RC- ja AS-napa kytkettynä laturi ei lähde lataamaan. Sitten kun, otin AS-navan pois, laturi menee jäykäksi, eli alkaisi lataamaan. Laturin käämi/säädin ottaa noin 4,5 A silloin virtaa akkujohdoista mitattuna. Varmaan ihan normi.
Nyt se jännin osuus. Ei ole väliä, onko Arduino päällä vai ei. Eli kun RC on vain kytketty, laturi jäykistyy. RC-napaan tulee koko ajan 3,9 VDC tällöin. Jos Arduino on päällä lähettäen pulssia, sen pystyy mittaamaan tästä navasta jännitevaihtelun ollessa tuolloin noin 8 V. Kun sekä RC-, että AS-napa ovat kytkettynä (jolloin laturi ei lataa), RC-navasta voi mitata noin 7,5 VDC.
Missään vaiheessa Arduino kortilla ei taikasavut nousseet ja mittailin sieltä kaikenlaisia napoja, niin ei niissä olleet jännitteet normaalista poikkeavia eikä 5 voltin johdossa ollut 0,08 ampeeria enempää virtaa missään vaiheessa. Eli näyttäisikö siltä, että tuonne RC-navalle jostain "vuotaa" nyt sähköä, joka jostain syystä herättää laturin? Luulen, että se jännite tulee laturin säätimeltä, eikä Arduinon päästä. Olen kyllä jo aikanaan kokeillut tätä laturia penkissä, eikä se silloin alkanut lataamaan. Mutta nyt jostain syystä se alkaisi lataamaan...
Toivottavasti näistä sepustuksista saa jotain selvää!
@ississ , joo eikös silloin jännite kuitenkin vaihtele lähdön mukaan? Vai onko vaihtelu n. 11,8-14,5 voltin suhteessa merkityksetöntä?
Käsitykseni mukaan tuolla suntilla ja kytkennällä pitäisi pystyä mittamaan periaatteessa lähes mitä tahansa jännitettä, koska kyseessä on vain jännite-eron mittaaminen. Mittasin myös vin-navoista suoraan, niin ei sen perusteella virran olisi pitänyt olla 76 ampeeria vaan lähellä nollaa. Ehkäpä kytkentä on sitten väärin.
@ississ , tarkoitin siis, että Arduino tarvitsee 5 V toimiakseen. Jos sen toteuttaisi kertomallasi tavalla, onko Arduinolle menevä jännite sopivissa rajoissa, jos tulo ennen noita kertomiasi komponentteja on välillä 11,8-14,5 V (vain esimerkki)? Vai onko niin, että tuohon Arduinon VIN-pinniin pitää vain tulojännite rajata niin, ettei se yli 12 volttia? Jos näin, niin korkeimmillaanhan se nousee vain sinne ehkä 14,5 volttiin. Eli jos tulon saisi rajoitettuna tuolla jännitteellä luokkaan 10 volttia, niin varmaankin toimisi?
MCP601 max käyttöjännite on 6 volttia.
Jos tuo virranmittauksen ongelma johtuu tuosta 12 voltista, niin voiko nuo jotenkin helposti erottaa, että niillä on omat maat? Eli tuo 12 voltin piiri pitäisi erottaa tuosta 5 voltin piiristä. Tai helpompaa olisi ehkä vaihtaa opampi, jolla laaja käyttäjännitealue. Kunhan olisi sama kytkentä kuin MCP601:llä!!!
@ississ , eli eikö toimi niin, että hankkisi opampin, jonka käyttöjännitealue on riittävä (esim. 2-18 volttia) ja kytkentä säilyisi muuten samana? Eli tuokin näyttäisi ampeerit väärin, jos sitä käytetään 5 voltilla? Näyttää siltä, että identtisellä kytkennällä olevia opampeja laajalla käyttöjännitealueella kyllä löytyisi.
Jos asia on näin, niin harmillinen juttu. Olin tällöin ehkä näköjään turhan hätäinen tuon apukortin kanssa, kun tilasin nuo valmiina kiinanmaalta, eikä enää sitä prosessia viitsi pyöräyttää läpi jo pelkästään kustannusten puolesta. Olisi pitänyt varmistaa kytkentä vielä täälläkin! Ei nimittäin pahemmin lähipiirissä ole elektroniikkaihmisiä. Enkä myöskään ala muutamia komponentteja hankkimaan kympin postikuluilla ja läträämään useiden juotosten kanssa reikäkortilla. Lisäksi tätähän yritin jo ja kaksi opampia tuhoutui, kun en tajunnut maadoittaa käpäliä. Siinä sitten ihmeteltiin, miksi antaa koko ajan täysiä ampeereja.
Jos tuo opampin vaihto ei riitä, niin täytyy kai hylätä tämä Fordin laturi ja hankkia perinteinen "tyhmälaturi". Virranmittauksenhan tällöin pitäisi onnistua, koska 12 voltin piiriä ei tällöin lainkaan tuotaisi samaan maapisteeseen muun kytkennän kanssa.
No nyt näkyy kyllä viestissä turhautumisen poikasta, mutta eipä se kaikki aina ole ihanaa ja mahtavaa! Vähän realismia peliin. =D
@ississ Jos ymmärrän oikein, niin pelkästään opampin vaihto ja sen käyttöjännite 14 V, tarkoittaisi myös lähtöä 0-14 V, niin silloin pitäisi olla lähdön jälkeen jotain elektroniikkaa, joka jälleen skaalaisi tämän lähdön alueelle 0-5 volttia. Toimisiko tässä yksinkertainen jännitteenjakokytkentä? Käsitykseni mukaan kyllä. Kytkennässähän apukortilla tuota 5 voltin jännitettä käyttää vain tuo opamp, joten käyttöjännite olisi helppo vaihtaa akkupiiriin.
Joka tapauksessa jotain pitää muuttaa, sanoisin että virran mittaus niin ei tarvitse muuttaa ihan kaikkea...Itse asiassa vaikka Ads1115 piirillä arduino ssa vois käyttää optoja data linjassa joten erotus onnistuu. Tuo 0n 4 vai 5 kanavainen 16bit ad muunnos onnistuisiko tolla lukee shuntista jännite häviön suoran ja siitä sais ampsutkin samalla
@ississ , hmm, niin, sama virtahan se täytyy miinuspuolella in kulkea. Onko tuossa muuten mitään isompaa muuttamista, jotta voisi mittauksen hoitaa miinupuolella?
Aloin miettiä vielä tuon apukortin kokonaan korvaavia muita vaihtoehtoja, mitenhän tällainen virta-anturi: Virta-anturi -75A ... +75A ACS709 moduuli
Tuossa on lähtöjännite suhteessa virtaan 28 mV/A, eli jos oikein lasken, niin 5000/1023 ~ 4,88... mV/bitti. Ja sitten vastaavasti 4,88...mV/porras / 28 mV/A ~ 0,17 A/porras. Eli mittaus olisi jo tuollaisenaan riittävän tarkka ilman mitään välipiirejä?
Latausvirran voisi rajoittaa vaikkapa 70 ampeeriin, jotta mennä yli anturin alueen.