Hi
Does the vspindle_5_1.ino work with the stand alone board(post #69) or dose the board or code need changing ?
You can use the Standalone board but you need to change the vspindle_5_1.ino code to use the same input-output pins as the board uses.
I haven't built this unit so I can't say if there are other changes needed.
I'm trying to update the standalone board to be pin compatible with the first schematic with some improvements to the zero cross detection. If someone sees any mistakes in the schematic please point them out and I will make the adjustments.
This integrated program that has been uploaded, how do you give and what we will install the program?
You got it wrong.
which will install the integrated program for ATmega328?
I will install v5.1 spindle it?
Sorry. I thought you were referring to the uploaded file above your post by sokomm,
... and you didn't give any links to help me.
You use an unzip program like WINZIP, etc....which will install the integrated program for ATmega328?
I will install v5.1 spindle it?
I used
Free RAR Extract Frog - Free download and software reviews - CNET Download.com
You then upload the unzipped file "vspindel_5_1.ino" with your Arduino IDE program to program your Arduino UNO board.
Your pinouts doesn't appear to follow mrendu43's sketch published on post # 172.
http://www.cnczone.com/forums/open-s...control-5.html
Hello,
Sorry for awaking such an old post but I'd like to build a 230 VAC motor controller with a standalone ATmega328.
I have read the 20 pages and honestly... I am lost !
Is there finally any working schematics/code ?
No, there isn't a complete guide. Member "straga" has working code. He posted his code and schematic here; https://github.com/straga/PIDSPINO
You will need to know enough about electricity and electronics to be able to use the rough details in this thread and straga's material to make your own. Keep safe when working with 220VAC.
Thanks for the link KOC62.
I'll give a try with this schematics and version 5.1 grabbed here..
Hi,
I tried with the original version found on Github (vspindel_v2) but I can't get it work...
The zero detection works fine, but whatever the potentiometer position, the same signal is always sent to the TRIAC :
Would you please help me to sort this out?
Or better, do someone has a working piece of code for 50 Hz.
I am totally lost with those constants and variables.
PS: RPM count works also perfectly well.
I don't have a working unit as I never completed this project.
Regarding the potentiometer (pot) changes, I have two suggestions;
a) you could remove the comment slashes (i.e. //) in front of lines;
151 // lcd.setCursor ( 10, 0 );
152 // lcd.print ((float)analogValue);
to display your pot settings for troubleshooting. you will need to re-compile (upload) the changes to try it out. This would let you see what the pot is sitting at as you change it.
If this works but not the triac pwm,
b) you then may need to check the PID parameters to see what is going on. It's the output ("analogValue") of the PID section that controls the triac along with the RPM pot setting. It may be possible that using a 50HZ line frequency will require a change in the pid parameters - but I don't know that and haven't reverse engineered how the pid values are chosen.
There is a way to override the pid output by modifying "analogValue" after the pid section to make it a manual control of motor RPM as a test, but I'll have to review the code to see where that could be done.
analogValue varies according to the pot position between 0 and 1002.
I have also displayed "Output" just after the myPID.Compute(); command.
I noticed it goes from 0 to 10000 in a couple of second just after the boot and remains to 10000.
Here is the whole code (there are some minor modifications: pins assignments and check on powerOn bypassed)
Code:#include LiquidCrystal.hLiquidCrystal lcd(9, 4, 5, 6, 7, 8); // Inputs #define triac_control 11 // Triac control - pin #define sensorPin A0 // potentiometer or MACH3 - pin #define powerOn 10 // Power switch - pin #define powerIndicator A2 // indicator GREEN LED -pin #define zero_detect 2 //Zero detect - pin #define hallsensor 3 //- pin // when using values in the main routine and IRQ routine must be volatile value volatile byte zero_bit = LOW; // declare IRQ flag unsigned int rpmcount; unsigned int rpm; unsigned long timeold; // PID #include PID_v1.h //Define Variables we'll be connecting to double Setpoint, Input, Output; //Define the aggressive and conservative Tuning Parameters //double consKp=4, consKi=0.2, consKd=1; //double consKp=0.4, consKi=0.001, consKd=1; //double consKp=4, consKi=0.2, consKd=1; //double consKp=1, consKi=0.4, consKd=0.01; //100% work //double consKp=0.4, consKi=0.001, consKd=1; double consKp=0.1, consKi=0.5, consKd=0.05; //Specify the links and initial tuning parameters PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT); int analogValue = 0; int analogmin = 0; int analogmax = 1023; float kDev = 24.4; // rpm to analog - exp: max rpm = 22000 , analogmax = 920 : rpm/analogmax = kDev = 25 void setup() { pinMode(triac_control, OUTPUT); digitalWrite(triac_control, 0); // Triac off pinMode(powerIndicator, OUTPUT); digitalWrite(powerIndicator, 0); // LED off pinMode(powerOn, INPUT); digitalWrite(powerOn, 1); // pull up on pinMode(zero_detect, INPUT); digitalWrite(zero_detect, 1); // pull up on pinMode(hallsensor, INPUT); digitalWrite(hallsensor, 1); // pull up on attachInterrupt(0, zero_fun, FALLING); // interrupt 0 digital pin 2 connected ZC circuit attachInterrupt(1, rpm_fun, FALLING); // interrupt 1 digital pin 3 connected hall sensor rpmcount = 0; rpm = 0; timeold = 0; // LCD detect lcd.begin(16,2); // initialize the lcd lcd.home (); // go home lcd.print("Hello, ARDUINO "); lcd.setCursor ( 0, 1 ); // go to the next line lcd.print (" vSpindel-2.0 "); delay(1000); lcd.clear(); //PID Input = rpm; Setpoint = analogValue; //turn the PID on myPID.SetMode(AUTOMATIC); myPID.SetOutputLimits(0, 10000); // v3 //myPID.SetOutputLimits(0, 9980); // limit are set to be delay in microseconds for triac fiering ( 8333 for 60hz, 10000 for 50hz line )9980 to limit max power. // we realy dont need full speed of 36000 } void loop() { //Power switch and indicator = ON/OFF if (!digitalRead(powerOn)) { digitalWrite(powerIndicator, 1); } else { digitalWrite(powerIndicator, 0); } //RPM counter and show on LCD if (rpmcount >= 50) { //Update RPM every 20 counts, increase this for better RPM resolution, //decrease for faster update //rpm = 60*1000/(millis() - timeold)*rpmcount; unsigned long time = millis() - timeold; float time_in_sec = (float)time / 1000; float impuls_time = (float)rpmcount / time_in_sec; rpm = (int)impuls_time*60; rpmcount = 0; //reset timeold = millis(); //set time if (rpm < 10000) { lcd.setCursor ( 0, 0 ); lcd.print ("RPM:"); lcd.setCursor ( 4, 0 ); lcd.print (" "); lcd.setCursor ( 5, 0 ); lcd.print (rpm); } else { lcd.setCursor ( 0, 0 ); lcd.print ("RPM:"); lcd.setCursor ( 4, 0 ); lcd.print (rpm); } } //PID analogValue = analogRead(sensorPin); lcd.setCursor (10, 0 ); lcd.print ((float)analogValue); Input = rpm; // Input = analogmax-Input+analogmin; // if (Input > analogmax) // Limit for max delay time 920*9 = 8280; // { // Input = analogmax; // } //139 = a * 20 + b ? 920 = a * 920 + b //analogValue =((781*analogValue)+109480)/900; float analog1 = 781*(float)analogValue; float analog2 = analog1+109480; float analog3 = analog2/900; analogValue = (int)analog3; Setpoint = analogValue*kDev; myPID.Compute(); lcd.setCursor (0, 1 ); lcd.print (Setpoint); myPID.Compute(); lcd.setCursor (9, 1 ); lcd.print (Output); analogValue = Output/kDev; analogValue = analogmax-analogValue+analogmin; if (analogValue > analogmax) { // Limit for max delay time 920*9 = 8280; analogValue = analogmax; } //analogValue = analogmax-analogValue+analogmin; // debug 1 Real potontiometr and virtual. // lcd.setCursor ( 10, 0 ); // lcd.print (Setpoint); // // lcd.setCursor ( 0, 1 ); // lcd.print (analog3); // debug 2 // lcd.setCursor ( 10, 0 ); // lcd.print ((float)analogValue); // // lcd.setCursor ( 0, 1 ); // lcd.print ((float)analogValue*9); // // lcd.setCursor ( 10, 1 ); // lcd.print (analog3*9); // lcd.setCursor ( 10, 0 ); // lcd.print (Input); // // // lcd.setCursor ( 0, 1 ); // lcd.print (Setpoint); // // lcd.setCursor ( 10, 1 ); // lcd.print (float(analogValue)); // lcd.setCursor ( 10, 1 ); // lcd.print (analogValue); //TRIAC delay control //if ((zero_bit == 1) && (digitalRead(powerOn)== 0)) { if (zero_bit == 1) { if (analogRead(sensorPin) > 0) { delayMicroseconds(analogValue * 9); // set value between 4 and 14 //delayMicroseconds(4000); digitalWrite(triac_control, 1); //triac on delayMicroseconds(100); digitalWrite(triac_control, 0); //triac off zero_bit = 0; // clear flag } } } void zero_fun() { // set bit zero_bit = 1; // if zero detect set bit == 1 } void rpm_fun() { rpmcount++; //Each rotation, this interrupt function is run }
Forgot the image:
You will notice I have bypassed the 33k resistors to test with a lower voltage after a transformer. But the behaviour is striclty the same with 230V.
Have you been able to get your controller to work?
If not, have you been able to test the triac circuit to see if controls the motor manually?
For example, the analogValue is forced to fall between 139 and 920 as limited by "analogmin" and "analogmax".
Hence you could add some code just above the triac control section as follows;
// force pot setting between 139 and 920
analogValue = map(analogRead(sensorPin), 0, 1023, 139, 920);
//TRIAC delay control
//if ((zero_bit == 1) && (digitalRead(powerOn)== 0)) {
.
.
.
I haven't tried this so you take the risk if you think it is worth it. The idea is to override the PID stuff to see if your triac is working properly with the code you have. If this works you then need to figure out the PID routine to see why it doesn't appear to work.
No, it doesn't work.
Whatever the pot position, the spindle turns at its maximum, except when the pot is set to 0.
analogValue goes from 139 to 920.
Here is the test code :
Code:analogValue = map(analogRead(sensorPin), 0, 996, 139, 920); lcd.setCursor (9, 1 ); lcd.print (analogValue); if (zero_bit == 1) { if (analogRead(sensorPin) > 0) { delayMicroseconds(analogValue * 9); // set value between 4 and 14 //delayMicroseconds(4000); digitalWrite(triac_control, 1); //triac on delayMicroseconds(100); digitalWrite(triac_control, 0); //triac off zero_bit = 0; // clear flag } }
OK.
Is it possible that you have the wrong opto-isolator for triggering your triac? Some of them use a "zero-cross" circuit inside that only allows OFF - ON operation, with no delay triggering.
Another test is to use your oscilloscope and have it triggered with the zero crossing detector pulse to synchronize your 'scope to your AC line frequency and then monitor the Arduino output pin that goes to your opto chip and see how your pulse position is varying with your RPM pot settings. This should confirm that your Arduino board is working correctly up to your triac opto-isolator chip.
Don't connect your 'scope to your AC line as you don't want to get a shock, or blow your AC circuit breaker.