PDA

Επιστροφή στο Forum : Arduino αλλαγή τιμής TCCR1B



selectronic
23-09-18, 07:37
Κύριοι καλημέρα,

έχω ένα προγραμματάκι που βγάζει PWM με μεταβλητό duty cycle ανάλογα με ένα pot. Θέλω όμως να μπορώ και να αλλάζω την συχνότητα μεταξύ κάποιων στάνταρ τιμών, το οποίο μπορώ να κάνω αλλάζοντας μία γραμμή στον κώδικα κάθε φορά (και μετά download στον Arduino).
Πως μπορώ να κάνω αυτή την αλλαγή στον κώδικα ανάλογα με πχ έναν εξωτερικό διακόπτη (ΟΝ=122.55Hz / OFF=490.2Hz)? Δεν με νοιάζει το κομμάτι που διακόπτη, το πως μπορώ να αλλάζω την τιμή αυτού του "TCCR1B (https://playground.arduino.cc/Main/TimerPWMCheatsheet)" (πχ από "TCCR1B = TCCR1B & B11111000 | B00000100;" σε "TCCR1B = TCCR1B & B11111000 | B00000011;") μέσω πχ "if .... else" στον κώδικα δεν ξέρω πως να κάνω.

Οι πιθανοί συνδυασμοί που αλλάζω:

TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
TCCR1B = TCCR1B & B11111000 | B00000100; // set timer 1 divisor to 256 for PWM frequency of 122.55 Hz
TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz

όλος ο κώδικας που έχω τώρα:




#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 8, 4, 5, 6, 7); // Blue 16x2 LCD

int LcdReadWrite = 3; // temp solution for LCD R/W pin...
int PWMout = 10; // PWM-out pin
int PWMvalue = 0; // create variable that is ADC/PWM value to print on LCD
float DutyCycle = 0.0; // create variable that stores actual PWM Duty Cycle

void setup() {
pinMode(LcdReadWrite, OUTPUT); // temp solution for LCD R/W pin...
digitalWrite(LcdReadWrite, LOW); // temp solution for LCD R/W pin...

analogReference (INTERNAL); // switching to Internal ~1.1Vref
pinMode(PWMout, OUTPUT); // Set PWM Pin as OUTPUT
lcd.begin(16, 2);

// Code for changing PWM Freq, from https://arduino-info.wikispaces.com/Arduino-PWM-Frequency?responseToken=007a74d2bfe1757a276fe25f3c 882f281
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
//
//TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
//TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
//TCCR1B = TCCR1B & B11111000 | B00000100; // set timer 1 divisor to 256 for PWM frequency of 122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz

}

void loop() {

// print the number of seconds since reset:
lcd.setCursor(0, 0);
lcd.print(millis() / 1000);

// Read 'value'
int value = analogRead (A2);

// Print 'value' to LCD
lcd.setCursor(4, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print(value);

// Calculate the PWM value depended on Pot value, ADC/4 (ADC = 0-1024 , PWM = 0-255)
PWMvalue = value / 4;
// Calculate the PWM Duty Cycle, (0-255 = 0-100%)
DutyCycle = PWMvalue / 2.55;

// Print 'PWMvalue' on LCD
lcd.setCursor(8, 0);
lcd.print(" ");
lcd.setCursor(8, 0);
lcd.print(PWMvalue);
// Print 'DutyCycle' on LCD (print BLANKS first)
lcd.setCursor(12, 0);
lcd.print(" ");
lcd.setCursor(12, 0);
lcd.print(DutyCycle);

// Printing "name Tags" on the 2nd Line of the LCD
lcd.setCursor(1, 1);
lcd.print("T");
lcd.setCursor(4, 1);
lcd.print("ADC");
lcd.setCursor(8, 1);
lcd.print("PWM");
lcd.setCursor(12, 1);
lcd.print("Duty");

// Output a PWM signal proportional to Pot value on PWMout pin
analogWrite(PWMout, PWMvalue);

//Delay to reduce LCD flicker
delay(200);
}




Ευχαριστώ εκ των προτέρων :)

elektronio
23-09-18, 09:12
Καλημέρα
είναι λίγο δυσνόητο το μήνυμα σου ως προς το τι θες να πετύχεις. Θες μόνο δύο περιοχές συχνοτήτων ελεγχόμενες με ένα διακόπτη ή θες κάτι να μπορείς να επιλέξει οποιαδήποτε περιοχή. Τι εννοείς δεν σε ενδιαφέρει το κομμάτι του διακόπτη αφού ανάλογα με τον διακόπτη θα γραφτεί και το πρόγραμμα.

Μπορείς να επιλέγεις οποιαδήποτε περιοχή συχνοτήτων από τις 5 με τους εξής τρόπους:
1. με ένα επιλογέα περιστροφικό 5 θέσεων
2. με ένα άλλο ποτενσιόμετρο σαν αυτό που έχεις (πέντε περιοχές τιμών αντίστασης χωρίς σαφή ένδειξη σε ποια περιοχή βρίσκεσαι)
3. rotary encoder
4. με διακοπτάκια dip switch (με τρία διακοπτάκια δυαδικά)

Με τους 1 και 4 τρόπους έχεις ένδειξη της επιλεγμένης περιοχής πάνω από το μέσο επιλογής.
Στις περιπτώσεις 2 και 3 δεν έχεις τέτοια ένδειξη οπότε θα πρέπει να προστεθεί κάποια ένδειξη περιοχής είτε σε LCD οθόνη αν έχεις και άλλες ενδείξεις είτε σε ένα 7 segment display.

Όλα τα παραπάνω εξαρτώνται και από το πόσα ποδαράκια Ι/Ο έχεις διαθέσιμα.

selectronic
23-09-18, 09:40
Αυτό που δεν μπορώ να κάνω είναι να αλλάζω την τιμή "TCCR1B = TCCR1B & B11111000 | B00000xxxx" όταν τρέχει το πρόγραμμα.
Δηλαδή μπορώ να διαβάζω ένα pot ή διακόπτη κτλ αλλά δεν ξέρω πως να κάνω το κομμάτι "αν switch=ΟΝ τότε (TCCR1B = TCCR1B & B11111000 | B00000001)" και "αν switch=OFF τότε (TCCR1B = TCCR1B & B11111000 | B00000010)"

Άσχετο αλλά μάλλον θα το κάνω με περιστροφικό διακόπτη και διαφορετικές αντιστάσεις σε κάθε πόδι για να χρησιμοποιήσω μόνο μία είσοδο του Arduino, οπότε αν διαβάζει με analogRead στο Χ ποδαράκι πχ 0-1V τότε θα βγάζει 120Hz, όταν διαβάζει 1-2V θα βγάζει 490Hz κτλ...

selectronic
23-09-18, 10:05
Πιο απλά θέλω όταν τρέχει το πρόγραμμα, να πατάω ένα κουμπί και να αλλάζει η συχνότητα του σήματος PWM από Χ σε Ψ.
Το πως θα καταλάβει ο arduino ότι πατήθηκε το κουμπί ξέρω πως να το κάνω, την αλλαγή συχνότητας δεν ξέρω πως να κάνω...

elektronio
23-09-18, 10:26
Τώρα παρατήρησα τον κώδικα και βλέπω ότι χρησιμοποιείς LCD οθόνη αν σου περισσεύει χώρος να δείξεις 1 ψηφίο (1-5) μπορείς να βάλεις ένα ποτενσιόμετρο (πιο απλό από τον επιλογέα με αντιστάσεις)
Στον κώδικα μπορείς να αλλάζεις την τιμή του TCCR1B με την swith. Θα μετατρέψεις την τιμή που διαβάζεις από το διακόπτη / ποτ κλπ σε τιμές ένα έως πέντε και σε κάθε γραμμή case θα βάλεις από μία γραμμή του κώδικα που τώρα αλλάζεις με το χέρι.
Μπορείς να βάλεις και επιπλέoν εντολές σε κάθε case για να δείχνεις στην οθόνη σε ποια περιοχή συχνότητας βρίσκεσαι.


switch (var) {
case1: //do something when var equals 1
break;
case2:
//do something when var equals 2
break;
default:
// if nothing else matches, do the default
// default is optional[/COLOR]
break;
}

selectronic
23-09-18, 10:35
Ευχαριστώ, το ψάχνω τώρα το πως δουλεύει η εντολή "switch" (https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/) :)

selectronic
23-09-18, 11:19
..Στον κώδικα μπορείς να αλλάζεις την τιμή του TCCR1B με την swith...

Δούλεψε μια χαρά, ευχαριστώ :))
Προς το παρών έκανα δοκιμή με το pot που έχω συνδεδεμένο αλλά τώρα που ξέρω πως, θα κάνω και τα υπόλοιπα!



// Code for changing PWM Freq, from https://arduino-info.wikispaces.com/Arduino-PWM-Frequency?responseToken=007a74d2bfe1757a276fe25f3c 882f281
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
//
//TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
//TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
//TCCR1B = TCCR1B & B11111000 | B00000100; // set timer 1 divisor to 256 for PWM frequency of 122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz

#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 8, 4, 5, 6, 7); // Blue 16x2 LCD

int LcdReadWrite = 3; // temp solution for LCD R/W pin...
int PWMout = 10; // PWM-out pin
int PWMvalue = 0; // create variable that is ADC/PWM value to print on LCD
int var = 0;
float DutyCycle = 0.0; // create variable that stores actual PWM Duty Cycle

void setup() {
pinMode(LcdReadWrite, OUTPUT); // temp solution for LCD R/W pin...
digitalWrite(LcdReadWrite, LOW); // temp solution for LCD R/W pin...

analogReference (INTERNAL); // switching to Internal ~1.1Vref
pinMode(PWMout, OUTPUT); // Set PWM Pin as OUTPUT
lcd.begin(16, 2);

}

void loop() {

// print the number of seconds since reset:
lcd.setCursor(0, 0);
lcd.print(millis() / 1000);

// Read 'value'
int value = analogRead (A2);

// Print 'value' to LCD
lcd.setCursor(4, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print(value);

lcd.setCursor(0, 1);
lcd.print("TT");
lcd.setCursor(4, 1);
lcd.print("ADC");

if (value < 512) {var=1;}
else if (value > 512) {var=2;}

switch (var) {
case 1:
TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz
break;
case 2:
TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
break;
};

lcd.setCursor(8, 0);
lcd.print(var);
lcd.setCursor(8, 1);
lcd.print("var");

PWMvalue = 128;
// Calculate the PWM Duty Cycle, (0-255 = 0-100%)
DutyCycle = PWMvalue / 2.55;

// Output a PWM signal proportional to Pot value on PWMout pin
analogWrite(PWMout, PWMvalue);

//Delay to reduce LCD flicker
delay(200);
}

nkarama
23-09-18, 15:04
Δηλαδή μπορώ να διαβάζω ένα pot ή διακόπτη κτλ αλλά δεν ξέρω πως να κάνω το κομμάτι "αν switch=ΟΝ τότε (TCCR1B = TCCR1B & B11111000 | B00000001)" και "αν switch=OFF τότε (TCCR1B = TCCR1B & B11111000 | B00000010)"


Ειλικρινά δεν μπορώ να καταλάβω τι ρωράς... την απάντηση την έχεις γράψει ήδη..... ???????



Δούλεψε μια χαρά, ευχαριστώ :))


if (value < 512) {var=1;}
else if (value > 512) {var=2;}

switch (var) {
case 1:
TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz
break;
case 2:
TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
break;
};



?????

Δηλαδή λες...
Αν η τιμή είναι 10 τότε το α είναι 1
Αν η τιμή είναι 20 τότε το α είναι 2

Αν το α είναι 1 τοτε αυτό...
Αν το α είναι 2 τότε εκείνο...

???? Δεν θα ήταν ποιο εύκολο να πεις:

αν η τιμή είναι 10 τότε αυτό...
αν η τιμή είναι 20 τότε εκείνο...



if (value < 512) {TCCR1B = TCCR1B & B11111000 | B00000011;}
else if (value > 512) TCCR1B = TCCR1B & B11111000 | B00000010;

elektronio
23-09-18, 16:11
Δούλεψε μια χαρά, ευχαριστώ :))
Προς το παρών έκανα δοκιμή με το pot που έχω συνδεδεμένο αλλά τώρα που ξέρω πως, θα κάνω και τα υπόλοιπα!



// Code for changing PWM Freq, from https://arduino-info.wikispaces.com/Arduino-PWM-Frequency?responseToken=007a74d2bfe1757a276fe25f3c 882f281
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
//
//TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
//TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
//TCCR1B = TCCR1B & B11111000 | B00000100; // set timer 1 divisor to 256 for PWM frequency of 122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz

#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 8, 4, 5, 6, 7); // Blue 16x2 LCD

int LcdReadWrite = 3; // temp solution for LCD R/W pin...
int PWMout = 10; // PWM-out pin
int PWMvalue = 0; // create variable that is ADC/PWM value to print on LCD
int var = 0;
float DutyCycle = 0.0; // create variable that stores actual PWM Duty Cycle

void setup() {
pinMode(LcdReadWrite, OUTPUT); // temp solution for LCD R/W pin...
digitalWrite(LcdReadWrite, LOW); // temp solution for LCD R/W pin...

analogReference (INTERNAL); // switching to Internal ~1.1Vref
pinMode(PWMout, OUTPUT); // Set PWM Pin as OUTPUT
lcd.begin(16, 2);

}

void loop() {

// print the number of seconds since reset:
lcd.setCursor(0, 0);
lcd.print(millis() / 1000);

// Read 'value'
int value = analogRead (A2);

// Print 'value' to LCD
lcd.setCursor(4, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print(value);

lcd.setCursor(0, 1);
lcd.print("TT");
lcd.setCursor(4, 1);
lcd.print("ADC");

if (value < 512) {var=1;}
else if (value > 512) {var=2;}

switch (var) {
case 1:
TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz
break;
case 2:
TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
break;
};

lcd.setCursor(8, 0);
lcd.print(var);
lcd.setCursor(8, 1);
lcd.print("var");

PWMvalue = 128;
// Calculate the PWM Duty Cycle, (0-255 = 0-100%)
DutyCycle = PWMvalue / 2.55;

// Output a PWM signal proportional to Pot value on PWMout pin
analogWrite(PWMout, PWMvalue);

//Delay to reduce LCD flicker
delay(200);
}


Αν είχες σκοπό να βάλεις μόνο τις δύο συχνότητες μπορούσες να το κάνεις πιο απλά με if ... else, σου έγραψα την switch για να χρησιμοποιήσεις όλες τις περιπτώσεις γιαυτό αναφέρω και από το 1 έως το 5.

selectronic
23-09-18, 18:56
Ειλικρινά δεν μπορώ να καταλάβω τι ρωράς... την απάντηση την έχεις γράψει ήδη..... ???????


Δηλαδή μπορώ να διαβάζω ένα pot ή διακόπτη κτλ αλλά δεν ξέρω πως να κάνω το κομμάτι "αν switch=ΟΝ τότε (TCCR1B = TCCR1B & B11111000 | B00000001)" και "αν switch=OFF τότε (TCCR1B = TCCR1B & B11111000 | B00000010)"


?????

Δηλαδή λες...
Αν η τιμή είναι 10 τότε το α είναι 1
Αν η τιμή είναι 20 τότε το α είναι 2

Αν το α είναι 1 τοτε αυτό...
Αν το α είναι 2 τότε εκείνο...

???? Δεν θα ήταν ποιο εύκολο να πεις:

αν η τιμή είναι 10 τότε αυτό...
αν η τιμή είναι 20 τότε εκείνο...



if (value < 512) {TCCR1B = TCCR1B & B11111000 | B00000011;}
else if (value > 512) TCCR1B = TCCR1B & B11111000 | B00000010;


Για το πρώτο μέρος του κώδικα, όταν έγραφα "switch" εννοούσα τον διακόπτη, όχι την εντολή, την οποία δεν ήξερα πριν την αναφέρει ο Μάρκος. Τα πρώτα βήματα κάνω με τον arduino βλέπεις ;)
Για το δεύτερο μέρος, σωστά το λες ότι δεν χρειάζεται η ενδιάμεση "var", απλώς ένα γρήγορο τεστ έκανα για να δω πως δουλεύει η εντολή "switch", θα συμμαζευτεί ο κώδικας ο οποίος είναι και μερικά τεστ έτσι κι αλλιώς, δεν θα είναι μονιμη κατασκευή αυτό που φτιάχνω, απλώς θέλω να κάνω μερικά πειράματα σε διάφορα τροφοδοτικά (50Hz και switching) με παλμικό φορτίο.



Αν είχες σκοπό να βάλεις μόνο τις δύο συχνότητες μπορούσες να το κάνεις πιο απλά με if ... else, σου έγραψα την switch για να χρησιμοποιήσεις όλες τις περιπτώσεις γιαυτό αναφέρω και από το 1 έως το 5.
Ναι, για περισότερες από δύο τιμές θα το κάνω, ο κώδικας που έβαλα ήταν μόνο ένα γρήγορο τεστ :)

nestoras
23-09-18, 19:09
....απλώς θέλω να κάνω μερικά πειράματα σε διάφορα τροφοδοτικά (50Hz και switching) με παλμικό φορτίο.


Τι οδηγεις με την εξοδο του arduino?

selectronic
23-09-18, 19:27
Το βάζω παρακάτω. Απλώς είμαι περίεργος να δω τι θα γίνει... Θα ξεκινήσω από χαμηλά πχ 30Hz και χαμηλό φορτίο πχ 20% του μέγιστου που μπορεί να σώσει το τροφοδοτικό και θα ανεβάζω συχνότητα και φορτίο (μέχρι να μου σκάσει κανένα τροφοδοτικό στην μάπα XD).

Στο πραγματικό κύκλωμα έχω βάλει ένα Darlington BD677 αντί ΒC546 για μεγαλύτερο ρεύμα εξόδου με λίγα mA από τον Arduino (overkill ίσως αλλά αυτό είχα) και για MOSFET ένα γομάρι 47Ν60.


http://www.hlektronika.gr/forum/attachment.php?attachmentid=75439&d=1537720002


http://www.hlektronika.gr/forum/attachment.php?attachmentid=75440&d=1537720022

nestoras
23-09-18, 19:29
Ωραιος. Απλα ηθελα να δω τη βαθμιδα εξοδου επειδη θα ηταν επικινδυνο να οδηγησεις απευθειας.

Να ποσταρεις και τα αποτελεσματα στο αλλο θεμα που ανοιξες.

selectronic
23-09-18, 19:37
ΟΚ, αλλά μην περιμένεις πολλά από το γκάτζετ-παλμογράφο μου :/
Έχω καταφέρει να δω το bounce στις επαφές ρελέ με αυτόν πάντως, οπότε πιστεύω ότι κάποιο overshoot θα το πιάσω, έστω και στο περίπου.... Θα δείξει.

http://www.hlektronika.gr/forum/attachment.php?attachmentid=75441&d=1537720642
http://www.hlektronika.gr/forum/attachment.php?attachmentid=75442&d=1537720643
http://www.hlektronika.gr/forum/attachment.php?attachmentid=75443&d=1537720645

nestoras
23-09-18, 20:49
Τι ρυθμο δειγματοληψιας εχει το gadget για time/div < 1ms ??

selectronic
23-09-18, 21:10
Μέχρι 1μS/div κατεβαίνει αλλά από την άλλη έχει bandwidth ή 20KHz ή 200KHz (δεν θυμάμαι πιο)...
Έχω μετρήσει το μεταβλητό duty cycle σε περίπου 60KHz που έβγαζε το chip σε παλμοτροφοδοτικό ανάλογα με το φορτίο, αλλά δεν έχω σοβαρό παλμογράφο για να δω πόσο σωστά έδειχνε την κυματομορφή.
Θυμάμαι σε reviews που είχα δει για το συγκεκριμένο που αναφέρανε ότι "είναι ΟΚ για μέχρι περίπου 50-100ΚΗz" αν δεν κάνω λάθος. Νομίζω βάζανε τετράγωνο και ανέβαζαν την συχνότητα μέχρι να αρχίσει να παραμορφώνει στην οθόνη?
Δεν θυμάμαι γιατί τον έχω καμιά δεκαριά χρόνια αυτόν, αν θυμάμαι καλά τον είχα πάρει 60ευρώ από το seed studio.

edit:
Τώρα υπάρχει το φτηνό DSO138 (https://www.seeedstudio.com/DSO-Shell-DIY-Kit-p-2929.html) με bandwidth 200ΚΗz και 10μS/Div με 25ευρώ (το βρίσκεις και σε eBay/Bangood/κτλ), από την μία 25ευρώ είναι τσάμπα για να έχεις κάτι που μπορεί να σου δείξει κυματομορφές (για να παίξεις με 555 ή για να διαγνώσεις βλάβες σε SMPS), από την άλλη αν με 50-100 ευρώ βρίσκεις μεταχειρισμένο κανονικό παλμογράφο αναλογικό δικάναλο με MHz bandwidth, ίσως να μην αξίζει το DSO. Από την άλλη δεν θα το κλάψεις και πολύ αν το κάψεις συν ότι είναι και μπαταρίας άρα 100% απομονωμένο από την γείωση/δίκτυο (που από ότι έχω καταλάβει είναι ο Νο1 λόγος που οι αρχάριοι καίνε τους παλμογράφους τους)...

https://statics3.seeedstudio.com/seeed/file/2017-08/bazaar541750_1.jpg

selectronic
23-09-18, 23:14
Τώρα που έκατσα να φτιάξω την επιλογή για όλες τις συχνότητες (5 σύνολο) κατάλαβα αυτό που έλεγε ο nkarama στο ποστ #8 (http://www.hlektronika.gr/forum/showthread.php?t=93291&p=852734&viewfull=1#post852734):
Δεν χρειάζεται η εντολή switch, με σκέτη "if .... else if .... else if" παίζει μια χαρά:




#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 8, 4, 5, 6, 7); // Blue 16x2 LCD

int LcdReadWrite = 3; // temp solution for LCD R/W pin...
int PWMout = 10; // PWM-out pin
int PWMvalue = 0; // create variable that is ADC/PWM value to print on LCD
int freq = 0;
float DutyCycle = 0.0; // create variable that stores actual PWM Duty Cycle

void setup() {
pinMode(LcdReadWrite, OUTPUT); // temp solution for LCD R/W pin...
digitalWrite(LcdReadWrite, LOW); // temp solution for LCD R/W pin...

analogReference (INTERNAL); // switching to Internal ~1.1Vref
pinMode(PWMout, OUTPUT); // Set PWM Pin as OUTPUT
lcd.begin(16, 2);

}

void loop() {

// print the number of seconds since reset:
lcd.setCursor(0, 0);
lcd.print(millis() / 1000);

// Read 'value'
int value = analogRead (A2);

// Print 'value' to LCD
lcd.setCursor(4, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print(value);

lcd.setCursor(0, 1);
lcd.print("TT");
lcd.setCursor(4, 1);
lcd.print("ADC");

if (value <= 200) {TCCR1B = TCCR1B & B11111000 | B00000101; freq=1;}
else if (value >= 201 && value <= 400) {TCCR1B = TCCR1B & B11111000 | B00000100; freq=2;}
else if (value >= 401 && value <= 600) {TCCR1B = TCCR1B & B11111000 | B00000011; freq=3;}
else if (value >= 601 && value <= 800) {TCCR1B = TCCR1B & B11111000 | B00000010; freq=4;}
else if (value >= 801) {TCCR1B = TCCR1B & B11111000 | B00000001; freq=5;}

lcd.setCursor(10, 0);
lcd.print(freq);
lcd.setCursor(9, 1);
lcd.print("freq");

// PWM value (0-255)
PWMvalue = 128;

// Output a PWM signal proportional to Pot value on PWMout pin
analogWrite(PWMout, PWMvalue);

//Delay to reduce LCD flicker
delay(200);

}


edit:
Μικρή αλλαγή για να γράφει την συχνότητα στην LCD (αντί για 1/2/3/4/5):




#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 8, 4, 5, 6, 7); // Blue 16x2 LCD

int LcdReadWrite = 3; // temp solution for LCD R/W pin...
int PWMout = 10; // PWM-out pin
int PWMvalue = 0; // create variable that is ADC/PWM value to print on LCD
float freq = 0;
float DutyCycle = 0.0; // create variable that stores actual PWM Duty Cycle

void setup() {
pinMode(LcdReadWrite, OUTPUT); // temp solution for LCD R/W pin...
digitalWrite(LcdReadWrite, LOW); // temp solution for LCD R/W pin...

analogReference (INTERNAL); // switching to Internal ~1.1Vref
pinMode(PWMout, OUTPUT); // Set PWM Pin as OUTPUT
lcd.begin(16, 2);

}

void loop() {

// print the number of seconds since reset:
lcd.setCursor(0, 0);
lcd.print(millis() / 1000);

// Read 'value'
int value = analogRead (A2);

// Print 'value' to LCD
lcd.setCursor(4, 0);
lcd.print(" ");
lcd.setCursor(4, 0);
lcd.print(value);

lcd.setCursor(0, 1);
lcd.print("TT");
lcd.setCursor(4, 1);
lcd.print("ADC");

if (value <= 200) {TCCR1B = TCCR1B & B11111000 | B00000101; freq=30.64;}
else if (value >= 201 && value <= 400) {TCCR1B = TCCR1B & B11111000 | B00000100; freq=122.55;}
else if (value >= 401 && value <= 600) {TCCR1B = TCCR1B & B11111000 | B00000011; freq=490.20;}
else if (value >= 601 && value <= 800) {TCCR1B = TCCR1B & B11111000 | B00000010; freq=3921.16;}
else if (value >= 801) {TCCR1B = TCCR1B & B11111000 | B00000001; freq=31372.55;}

lcd.setCursor(9, 0);
lcd.print(freq);
lcd.setCursor(10, 1);
lcd.print("freq");

// PWM value (0-255)
PWMvalue = 128;

// Output a PWM signal proportional to Pot value on PWMout pin
analogWrite(PWMout, PWMvalue);

//Delay to reduce LCD flicker
delay(200);

}

nestoras
24-09-18, 03:59
Σε ρωτησα για τη συχνοτητα δειγματοληψιας γιατι παιζει πολυ σημαντικο ρολο στην απεικονηση.

Πχ, ο dso που εβαλες εχει 1M sample/sec. Αυτο σημαινει οτι στα 200KHz bandwidth που αναφερει θα καταφερει να παρει μονο 5 δειγματα ανα περιοδο (με πιο απλα λογια: θα ενωσει 5 κουκιδες για να απεικονισει ολοκληρη την περιοδο ενος σηματος συχνοτητας 200KHz).

Αν ειναι "ψηφιακο" τεραγωνο το σημα δε θα εχεις μεγαλο προβλημα αλλα στα αναλογικα θα σου "ζωγραφισει" κατι που κατα πασα πιθανοτητα δεν ανταποκρινεται στην πραγματικοτητα. Βεβαια ο κατασκευαστης ειναι καλλυμενος απο τον Nyquist! :-D

Πολλα spikes παιζουν σε διαρκειες της ταξης των ns οποτε μην περιμενεις να πιασεις κατι μεγαλης συχνοτητας.

Παρολαυτα αξιζει τον κοπο να ασχοληθεις με το project σου και να μας ενημερωνεις για τα αποτελεσματα!

Καλη συνεχεια!

selectronic
24-09-18, 07:05
Ε ναι, μην περιμένουμε και θαύματα με 25€!
Όταν έγραψα για "διάγνωση βλάβης σε SMPS" δεν εννοούσα να δεις spikes ή να τεστάρεις το πόσο καλά δουλεύει ένα snubber που έφτιαξες, πιο προς το "βγάζει παλμούς ο controller?" έλεγα.
Γι' αυτό και δεν είμαι σίγουρος τι θα δω από overshoot όταν αφαιρώ απότομα το φορτίο, θέλει και ακρίβεια και ταχύτητα. Πάντως δεν μπορεί, κάτι θα δείξει (αν συμβαίνει βέβαια κάτι τέτοιο).