Advertisement
Guest User

Untitled

a guest
May 26th, 2020
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Electronic Load
  3.  * http://www.kerrywong.com
  4.  * 10/2013
  5.  */
  6. #include <SPI.h>
  7. #include <LiquidCrystal.h>
  8. #include <Encoder.h>
  9. #include <SPI.h>
  10.  
  11. //LCD pins
  12. const int pinRS = 2;
  13. const int pinEn = 3;
  14. const int pinD4 = 4;
  15. const int pinD5 = 7;
  16. const int pinD6 = 8;
  17. const int pinD7 = 9;
  18.  
  19. //analog pin 5
  20. const int pinLoadVoltage = 5;
  21.  
  22. //MCP4921 SPI
  23. const int PIN_CS = 10;
  24.  
  25. const int BTN_RESET = 14;
  26. const int BTN_RANGE_X2 = 15;
  27. const int BTN_MODE = 16;
  28. const int BTN_ENC = 17;
  29.  
  30. const int IDX_BTN_RESET = 0;
  31. const int IDX_BTN_RANGE_X2 = 1;
  32. const int IDX_BTN_MODE = 2;
  33. const int IDX_BTN_ENC = 3;
  34. const int LOOP_MAX_COUNT = 2000;
  35.  
  36. int DACGain = 1; //default gain 1xVref.
  37.  
  38. int loadMode = 0; // 0: Constant Current, 1: Constant Power
  39. const float EXT_REF_VOLTAGE = 0.333;
  40.  
  41. LiquidCrystal lcd(pinRS, pinEn, pinD4, pinD5, pinD6, pinD7);
  42. Encoder currentAdjEnc(5, 6);
  43.  
  44. int buttons[]={BTN_RESET, BTN_RANGE_X2, BTN_MODE, BTN_ENC};
  45. int buttonReadings[4];
  46. int lastButtonStates[]={HIGH, HIGH, HIGH, HIGH};
  47. int currentButtonStates[]={HIGH, HIGH, HIGH, HIGH};
  48. long lastDebounceTime[4];
  49.  
  50. long oldEncPosition = -999;
  51. long curEncPosition = 0;
  52. int DACSetStep = 1;
  53. int encoderValue = 0;
  54. int loopCounter = 0;
  55. int DACSetValue = 0;
  56.  
  57. long ADSum = 0;
  58.  
  59. float vLoad = 0.0;
  60. float setPower = 0.0;
  61. float setCurrent = 0.0;
  62.  
  63. void setup()
  64. {
  65.     for (int i = 0 ; i < 4 ; i++) {
  66.         pinMode(buttons[i], INPUT);
  67.         digitalWrite(buttons[i], HIGH);
  68.     }
  69.    
  70.     pinMode(PIN_CS, OUTPUT);
  71.     SPI.begin();  
  72.     SPI.setClockDivider(SPI_CLOCK_DIV2);
  73.  
  74.     lcd.begin(20, 4);
  75. }
  76.  
  77. void getCurrentEncPosition()
  78. {
  79.     curEncPosition = currentAdjEnc.read() / 4;
  80.    
  81.     if (curEncPosition != oldEncPosition) {
  82.         if (curEncPosition > oldEncPosition) {
  83.             encoderValue += DACSetStep;
  84.            
  85.             if (encoderValue > 4095) encoderValue = 4095;
  86.         } else {
  87.             encoderValue -= DACSetStep;
  88.            
  89.             if (encoderValue < 0) encoderValue = 0;
  90.         }
  91.        
  92.         oldEncPosition = curEncPosition;
  93.        
  94.         if (loadMode == 0) //Constant Current mode
  95.         {
  96.             setDACOutput(encoderValue);
  97.         } else { //Constant Power mode
  98.             setDACOutput(DACSetValue);
  99.         }
  100.     }
  101. }
  102.  
  103. //Buffered DAC output
  104. void setDACOutput(unsigned int val)
  105. {
  106.     byte lByte = val & 0xff;
  107.     //                      SHDN     GA            BUF
  108.     byte hByte = val >> 8 | 0x10 | DACGain << 5 | 1 << 6;
  109.    
  110.     PORTB &= 0xfb;
  111.     SPI.transfer(hByte);
  112.     SPI.transfer(lByte);
  113.     PORTB |= 0x4;    
  114. }
  115.  
  116. void displayStatus()
  117. {  
  118.     lcd.clear();    
  119.  
  120.     //average load voltage
  121.     vLoad = ADSum * 1.0 / (float) LOOP_MAX_COUNT / 1024.0 * 5.0  * (0.974 + 21.91) / 0.974;
  122.  
  123.     if (loadMode == 0) //Constant Current
  124.     {
  125.         float vSense = 1.0 * encoderValue / 4096.0 * EXT_REF_VOLTAGE;
  126.         float i = 3 * 10 * vSense; // 3 sets of MOSFET in parallel, 0.1 ohm
  127.         if  (DACGain == 0) i *=2; // x2
  128.    
  129.         lcd.print("CI,I Set=");
  130.    
  131.         if (i < 1.0) {
  132.             lcd.print(i * 1000,0);
  133.             lcd.print(" mA");
  134.         } else {
  135.             lcd.print(i ,2);
  136.             lcd.print(" A");
  137.         }
  138.     } else { //Constant Power
  139.         setPower = (float) encoderValue / 20.0; //approximately 0-200W
  140.  
  141.         lcd.print("CP, P Set=");        
  142.         if (vLoad > 0.5) {//minimum 0.5V
  143.             setCurrent = setPower / (float) vLoad;
  144.            
  145.             //desired sense voltage. Since we have 3
  146.             //sets of MOSFETS, the results are devided
  147.             //by 3 and multipled by the value of the sense
  148.             //resistor
  149.             float vSense = setCurrent / 4.0 * 0.1;
  150.          
  151.             DACSetValue = (int) (vSense/EXT_REF_VOLTAGE * 4096.0 + 0.5);
  152.  
  153.             if (setCurrent < 10.0) {
  154.                 DACGain = 1;                
  155.             } else {
  156.                 DACGain = 0;
  157.                 DACSetValue = (int) ((float) DACSetValue / 2.0 + 0.5);
  158.             }                        
  159.            
  160.             if (setPower >= 100.0) {
  161.                 lcd.print(setPower, 1);
  162.             }
  163.             else {
  164.                lcd.print(setPower, 2);    
  165.             }
  166.         } else {
  167.             setPower = 0;
  168.             lcd.print(setPower, 2);
  169.         }
  170.        
  171.         setDACOutput(DACSetValue);
  172.         lcd.print("W");
  173.     }
  174.    
  175.     lcd.setCursor(0, 1);
  176.     lcd.print("LOAD V=");
  177.     lcd.print(vLoad, 2);
  178.     lcd.print(" V");        
  179. }
  180.  
  181. void loop()
  182. {
  183.     int idx = 0;
  184.    
  185.     for (int i = 0 ; i < 4; i++) {
  186.         buttonReadings[i] = digitalRead(buttons[i]);
  187.        
  188.         if (buttonReadings[i] != lastButtonStates[i]) lastDebounceTime[i] = millis();
  189.        
  190.         if (millis() - lastDebounceTime[i] > 50) { //debouncing the buttons
  191.             if (currentButtonStates[i] != buttonReadings[i]) {
  192.                 currentButtonStates[i] = buttonReadings[i];                                
  193.                
  194.                 //actions
  195.                 if (currentButtonStates[i] == LOW) {
  196.                     switch (i) {
  197.                         case IDX_BTN_RESET:
  198.                         //reset output current to 0
  199.                            encoderValue = 0;
  200.                            DACSetValue = 0;
  201.                            break;
  202.                         case IDX_BTN_RANGE_X2:
  203.                         //switch between 100W/200W maximum power mode
  204.                             DACGain = DACGain == 1? 0 : 1;
  205.                            
  206.                             if (loadMode == 0) {
  207.                                 setDACOutput(encoderValue);
  208.                             }
  209.                             break;
  210.                         case IDX_BTN_MODE:
  211.                         //switch between constant current and constant power
  212.                             loadMode = loadMode == 1? 0 : 1;
  213.                             break;
  214.                         case IDX_BTN_ENC:
  215.                         //cycle through different encoder steps: 1/10/100
  216.                             DACSetStep *= 10;
  217.                            
  218.                             if (DACSetStep > 100) DACSetStep = 1;
  219.                             break;
  220.                     }
  221.                 }
  222.             }
  223.         }
  224.        
  225.         lastButtonStates[i] = buttonReadings[i];
  226.     }        
  227.  
  228.     getCurrentEncPosition();    
  229.     loopCounter++;
  230.    
  231.     // used to smooth out the analogRead results
  232.     ADSum += analogRead(pinLoadVoltage);
  233.    
  234.     if (loopCounter == LOOP_MAX_COUNT) {
  235.         displayStatus();
  236.         loopCounter = 0;
  237.         ADSum = 0;
  238.     }
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement