Ad Widget

Collapse

Announcement

Collapse
No announcement yet.

PWM controlled LCR-0202 test with temperature indication

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PWM controlled LCR-0202 test with temperature indication

    Hi everybody,

    I'm doing some tests on some cheap LDRs called LCR-0202 (they can be found on various cheap music equipments), that I want to share.
    The purpose is to find a correlation between the PWM used to control them (supplied with 5V), and their resistance.

    The needed material is:
    - an Arduino (I'm using a Mega 2560, but every Arduino can be used, from Nano to Uno to Due, etc...);
    - a DHT22 temperature and humidity sensor;
    - a PCA9685 16 channel 12 bit PWM controller;
    - up to 16 LCR-0202 to be tested (the limit is the number of PWM outputs of the PCA9685 and the number of analog inputs of the Arduino);
    - one LED to have a visual feedback of the actual PWM;
    - a 20x4 LCD screen (can be a 16x2 too, it just needs to be redrawn).

    In the attached photos you'll see the values of four LCR-0202s shown on screen:
    Second line shows the actual PWM command (the lower the value, the lower the current through the led, so the higher the resistance of the LDR), and the actual ambient temperature.
    Third and fourth lines show the actual value in Ohms of the four LDRs.

    This is the code:

    Code:
    #include <Wire.h>
    
    //to manage the LCR-0202s
    #include <Adafruit_PWMServoDriver.h>
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    //just to show results
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 20, 4);
    
    //to read ambient temperature
    #include <SimpleDHT.h>
    int pinDHT22 = 2;
    SimpleDHT22 dht22;
    float temperature = 0;
    float humidity = 0;
    
    //just an array of 2^n
    int pwm_values[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095};
    
    //analog readings in voltage dividers
    float a_read1 = 0;
    float a_read2 = 0;
    float a_read3 = 0;
    float a_read4 = 0;
    
    //LCR-0202 initial resistance values 
    float LCR1_ohm = 0;
    float LCR2_ohm = 0;
    float LCR3_ohm = 0;
    float LCR4_ohm = 0;
    
    //define "leak" resistors in voltage dividers
    float bottomR1_ohm = 1000;
    float bottomR2_ohm = 1000;
    float bottomR3_ohm = 1000;
    float bottomR4_ohm = 1000;
    
    void setup() {
      //PWM startup
      pwm.begin();
      pwm.setPWMFreq(500); //to avoid wavering of the light
    
      //LCD startup
      lcd.init();
      lcd.backlight();
      lcd.clear();
    }
    
    void loop() {
      for (int i = 0; i < 13; i++) {
        for (int led_num = 0; led_num < 6; led_num++) {
          pwm.setPWM(led_num, 0, (4095 - pwm_values[i]));
    
        }
        show_values(i);
      }
    }
    
    void show_values(int i) {
      lcd.clear();
      lcd.print("Robi's LCR-0202 Test");
    
      lcd.setCursor(0, 1);
      lcd.print("PWM ");
      lcd.print(pwm_values[i]);
    
      lcd.setCursor(10, 1);
      dht22.read2(pinDHT22, &temperature, &humidity, NULL);
      lcd.print("Temp ");
      lcd.print(temperature);
    
      lcd.setCursor(0, 2);
      a_read1 = analogRead(0);
      LCR1_ohm = ((1023 * bottomR1_ohm) / a_read1) - bottomR1_ohm;
      lcd.print(LCR1_ohm);
    
      lcd.setCursor(10, 2);
      a_read2 = analogRead(1);
      LCR2_ohm = ((1023 * bottomR2_ohm) / a_read2) - bottomR2_ohm;
      lcd.print(LCR2_ohm);
    
      lcd.setCursor(0, 3);
      a_read3 = analogRead(2);
      LCR3_ohm = ((1023 * bottomR3_ohm) / a_read3) - bottomR3_ohm;
      lcd.print(LCR3_ohm);
    
      lcd.setCursor(10, 3);
      a_read4 = analogRead(3);
      LCR4_ohm = ((1023 * bottomR4_ohm) / a_read4) - bottomR4_ohm;
      lcd.print(LCR4_ohm);
    
      delay(2000);
    }

  • #2
    Click image for larger version

Name:	LCR-0202 PWM0016.jpeg
Views:	1
Size:	96.6 KB
ID:	848079

    Click image for larger version

Name:	LCR-0202 PWM0004.jpeg
Views:	1
Size:	91.0 KB
ID:	848080

    Click image for larger version

Name:	LCR-0202 PWM0001.jpeg
Views:	1
Size:	93.9 KB
ID:	848081

    Comment


    • #3
      Click image for larger version

Name:	LCR-0202 PWM2048.jpeg
Views:	1
Size:	94.0 KB
ID:	848082

      Click image for larger version

Name:	LCR-0202 PWM1024.jpeg
Views:	1
Size:	95.1 KB
ID:	848083

      Click image for larger version

Name:	LCR-0202 PWM0128.jpeg
Views:	1
Size:	97.5 KB
ID:	848084

      Comment


      • #4
        Last one, with the lowest resistance.

        Has anyone done some similar tests on those LDRs?

        Click image for larger version

Name:	LCR-0202 PWM4095.jpeg
Views:	1
Size:	93.4 KB
ID:	848085

        Comment


        • #5
          Cool tests.

          Now, do you feed the input LED directly from 5V ? That means driving the LED with maximum GPIO current available, right?
          I understand the mean-LED-current is directly proportional to Duty Cycle and mean-LED-current to output resistance is given in datasheet - how do your findings match that?

          Honestly I am very surrised by huge spread at low duty/low mean LED current.
          Did you find anything interesting in humidity and temperature dependency?

          Comment


          • #7
            Exactly, and the PWM frequency is set to 500 Hz just because at 50 Hz you can see some "lumen ripple", so I just go one order of magnitude higher.

            The board has some internal 220 Ohm resistors to save the GPIOs, so the maximum current is around 14 mA.
            Just to note, the GPIOs have 10 mA capability as sources and 25 mA as sinks. I've used the latter configuration.

            Looking at page 3 of the datasheet, the shown resistance is higher than what I've seen, but as you can see there are very different values on the four samples.
            What's not as expected is on the lowest PWM side, because I cannot go above 100 kOhm.
            I've noticed that the driver keeps the led slightly on even at zero, probably due to the fact that the library is intended for servos and not for leds.

            No modifications related to humidity (not even tested, the package is perfectly sealed, while I expect a strong dependency on temperature, but I still have to do tests. I have an oven with the "levitation" option, and I will do some further tests with it.

            Of course all the data will be then transmitted through the serial port into the pc, to simplify the download and analysis of the data.

            Comment


            • #8
              Originally posted by Roberto View Post
              What's not as expected is on the lowest PWM side, because I cannot go above 100 kOhm.
              I've noticed that the driver keeps the led slightly on even at zero, probably due to the fact that the library is intended for servos and not for leds.
              I see you use the delay of 2s while the datasheet mentions the dark resistance is achieved after 10s - that might be a factor.
              Another one might be pull-up at ADC - no kidding, some micros will keep the pull-up in adc mode unless set otherwise.

              Just disconnect the input to see if the real dark resistance is getting measured properly.

              Otherwise you're still just at 10bits adc resolution, with effectively no more than 9 bits to be trusted - if you're lucky. Expect no precision above 10k measurement or adjust the lower resistor in divider.



              Edit:

              Another issue: you set the PWM and start the measuring and displaying pretty much immediately, thus giving not time to settle the resistance.
              I suggest you add another delay after setting the PWM value and before the reading and displaying function:

              Code:
              void loop() {
                for (int i = 0; i < 13; i++) {
                  for (int led_num = 0; led_num < 6; led_num++) {
                    pwm.setPWM(led_num, 0, (4095 - pwm_values[i]));
              
                  }
                  [I][B]delay(10000);[/B][/I]
                  show_values(i);
                }
              }
              Last edited by darkfenriz; 12-28-2017, 05:01 PM.

              Comment


              • #9
                Thanks darkfenriz,

                I came out with the fact that there's never a complete switch off of the leds (at least I've never succeded into, looking at the feedback leds), so one option is to "mix" two channels on one LDR with an higher series resistor, to have virtually 24 bit of resolution. I tried some solutions found on the net, but none of them really works.

                Good idea the delay before the reading. I've moved the 2 seconds delay out of the show_values to before the call of the subroutine, to help the LDRs stabilize their values.

                As for the 10 seconds delay, it's not needed. I've tested with 10k resistor in series with one LDR and in 2 seconds it switches to infinity (see plots below). The point is that with multiple readings over the time, the resistance is more constant now. I've also increased the PWM frequency, to further dampen any influence on "ripple" on the lumen of the led, so on resistance.

                Here the values I've obtained:
                - first column the PWM value
                - second column the temperature in °C
                - third column the resistance of the LDR with 10k in series on the led side;
                - other columns the resistance of other LDRs with only the "onboard" 220 Ohm resistance.

                Code:
                PWM Temp R1_Ohm R2_Ohm R3_Ohm R4_Ohm
                
                0  23.50  inf  92000.00  62937.50  28228.57
                1  23.50  inf  25921.05  23357.14  13208.33
                2  23.50  inf  14044.12  12824.32  8472.22
                4  23.50  inf  10000.00  9128.71  5314.81
                8  23.50  inf  6255.32  4500.00  3428.57
                16  23.50  inf  3758.14  3467.25  2491.47
                32  23.50  inf  2552.08  2343.14  1330.30
                64  23.50  101300.00  1340.96  1325.00  1037.85
                128  23.50  33100.00  1195.28  1126.82  520.06
                256  23.50  14984.37  908.58  386.18  430.77
                512  23.50  6930.23  444.92  497.80  393.73
                1024  23.50  4328.12  461.43  474.06  212.09
                2048  23.50  2788.89  223.68  174.51  139.20
                4095  23.50  1650.26  161.18  152.03  124.18
                
                0  23.50  inf  84250.00  72071.43  30968.75
                1  23.50  inf  27416.67  20312.50  12460.53
                2  23.50  inf  16947.37  12640.00  8385.32
                4  23.50  inf  9882.98  8932.04  5912.16
                8  23.50  inf  6255.32  5730.26  3409.48
                16  23.50  inf  3059.52  2965.12  2289.39
                32  23.50  inf  2090.63  2000.00  1532.18
                64  23.50  101300.00  1459.13  1407.06  1075.05
                128  23.50  32000.00  1096.31  1054.22  797.89
                256  23.50  14984.37  569.02  524.59  484.76
                512  23.50  7317.07  557.08  576.27  438.82
                1024  23.50  4559.78  538.35  203.53  216.41
                2048  23.50  2456.08  217.86  280.35  231.05
                4095  23.50  1650.26  161.18  152.03  124.18
                
                0  23.50  inf  84250.00  67200.00  30000.00
                1  23.50  inf  25230.77  22790.70  13208.33
                2  23.50  inf  14984.37  13614.29  8742.86
                4  23.50  inf  8472.22  7895.65  5515.92
                8  23.50  inf  4982.46  4812.50  3526.55
                16  23.50  inf  2919.54  2860.38  2247.62
                32  23.50  inf  2653.57  1699.21  1429.93
                64  23.50  112666.67  1519.70  1441.53  1100.62
                128  23.50  32000.00  1131.25  1083.50  810.62
                256  23.50  14984.37  952.29  480.46  457.27
                512  23.50  6992.19  474.06  515.56  403.29
                1024  23.50  4412.70  497.80  278.75  171.82
                2048  23.50  2444.44  237.00  283.56  229.57
                4095  23.50  1643.41  161.18  153.33  124.18
                
                0  23.50  inf  84250.00  72071.43  30968.75
                1  23.50  inf  25230.77  22250.00  13013.70
                2  23.50  inf  15500.00  13826.09  8742.86
                4  23.50  inf  9029.41  8300.00  5686.27
                8  23.50  inf  5557.69  5162.65  3671.23
                16  23.50  inf  3486.84  3244.81  2376.24
                32  23.50  inf  2432.89  2268.37  1671.02
                64  23.50  112666.67  1538.46  1471.01  1109.28
                128  23.50  29088.24  846.57  901.49  733.90
                256  23.50  15238.10  877.06  480.46  463.52
                512  23.50  7250.00  529.15  554.71  424.79
                1024  23.50  4529.73  342.52  195.09  231.05
                2048  23.50  2679.86  186.77  166.48  178.57
                4095  23.50  1643.41  159.86  153.33  124.18
                And here the updated code:

                Code:
                #include <Wire.h>
                
                //to manage the LCR-0202s
                #include <Adafruit_PWMServoDriver.h>
                Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
                
                //just to show results
                #include <LiquidCrystal_I2C.h>
                LiquidCrystal_I2C lcd(0x27, 20, 4);
                
                //to read ambient temperature
                #include <SimpleDHT.h>
                int pinDHT22 = 2;
                SimpleDHT22 dht22;
                float temperature = 0;
                float humidity = 0;
                
                //just an array of 2^n
                int pwm_values[] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095};
                
                //analog readings in voltage dividers
                float a_read1 = 0;
                float a_read2 = 0;
                float a_read3 = 0;
                float a_read4 = 0;
                
                //LCR-0202 initial resistance values
                float LCR1_ohm = 0;
                float LCR2_ohm = 0;
                float LCR3_ohm = 0;
                float LCR4_ohm = 0;
                
                //define "leak" resistors in voltage dividers
                float bottomR1_ohm = 1000;
                float bottomR2_ohm = 1000;
                float bottomR3_ohm = 1000;
                float bottomR4_ohm = 1000;
                
                void setup() {
                  //PWM startup
                  pwm.begin();
                  pwm.setPWMFreq(1500); //to avoid wavering of the light
                
                  //LCD startup
                  lcd.init();
                  lcd.backlight();
                  lcd.clear();
                
                  // Serial startup
                  Serial.begin(9600);
                }
                
                void loop() {
                  for (int i = 0; i < 14; i++) {
                    for (int led_num = 0; led_num < 6; led_num++) {
                      pwm.setPWM(led_num, 0, (4095 - pwm_values[i]));
                    }
                    delay(2000);
                    show_values(i);
                  }
                }
                
                void show_values(int i) {
                  lcd.clear();
                  lcd.print("Robi's LCR-0202 Test");
                
                  lcd.setCursor(0, 1);
                  lcd.print("PWM ");
                  lcd.print(pwm_values[i]);
                  Serial.print(pwm_values[i]);
                  Serial.print("  ");
                
                  lcd.setCursor(10, 1);
                  dht22.read2(pinDHT22, &temperature, &humidity, NULL);
                  lcd.print("Temp ");
                  lcd.print(temperature);
                  Serial.print(temperature);
                  Serial.print("  ");
                
                  lcd.setCursor(0, 2);
                  a_read1 = analogRead(0);
                  LCR1_ohm = ((1023 * bottomR1_ohm) / a_read1) - bottomR1_ohm;
                  lcd.print(LCR1_ohm);
                  Serial.print(LCR1_ohm);
                  Serial.print("  ");
                
                  lcd.setCursor(10, 2);
                  a_read2 = analogRead(1);
                  LCR2_ohm = ((1023 * bottomR2_ohm) / a_read2) - bottomR2_ohm;
                  lcd.print(LCR2_ohm);
                  Serial.print(LCR2_ohm);
                  Serial.print("  ");
                
                  lcd.setCursor(0, 3);
                  a_read3 = analogRead(2);
                  LCR3_ohm = ((1023 * bottomR3_ohm) / a_read3) - bottomR3_ohm;
                  lcd.print(LCR3_ohm);
                  Serial.print(LCR3_ohm);
                  Serial.print("  ");
                
                  lcd.setCursor(10, 3);
                  a_read4 = analogRead(3);
                  LCR4_ohm = ((1023 * bottomR4_ohm) / a_read4) - bottomR4_ohm;
                  lcd.print(LCR4_ohm);
                  Serial.println(LCR4_ohm);
                }

                Comment


                • #10
                  Same values, expressed in 10 bit format:

                  Code:
                  0  23.10  0.00  12.00  15.00  33.00
                  1  23.00  3.00  39.00  45.00  76.00
                  2  23.00  13.00  64.00  72.00  111.00
                  4  23.00  32.00  102.00  111.00  156.00
                  8  23.10  64.00  161.00  174.00  227.00
                  16  23.10  101.00  261.00  273.00  324.00
                  32  23.00  177.00  314.00  333.00  403.00
                  64  23.10  273.00  423.00  442.00  509.00
                  128  23.10  374.00  519.00  517.00  581.00
                  256  23.10  455.00  569.00  571.00  642.00
                  512  23.00  525.00  600.00  816.00  784.00
                  1024  23.00  619.00  672.00  824.00  863.00
                  2048  23.00  773.00  856.00  802.00  834.00
                  4095  23.00  809.00  881.00  888.00  911.00
                  
                  0  23.00  0.00  13.00  13.00  33.00
                  1  23.00  2.00  42.00  48.00  71.00
                  2  23.00  13.00  61.00  69.00  107.00
                  4  23.00  29.00  92.00  103.00  150.00
                  8  23.00  61.00  151.00  164.00  220.00
                  16  23.00  102.00  204.00  221.00  331.00
                  32  23.00  187.00  336.00  351.00  412.00
                  64  23.00  279.00  445.00  456.00  516.00
                  128  23.00  329.00  449.00  565.00  640.00
                  256  23.00  519.00  621.00  606.00  664.00
                  512  23.00  539.00  617.00  620.00  824.00
                  1024  23.00  636.00  687.00  711.00  867.00
                  2048  23.00  777.00  827.00  787.00  827.00
                  4095  23.00  809.00  881.00  888.00  911.00
                  
                  0  23.00  0.00  13.00  16.00  35.00
                  1  23.00  3.00  38.00  43.00  74.00
                  2  23.00  13.00  59.00  67.00  106.00
                  4  23.00  32.00  90.00  102.00  148.00
                  8  23.00  60.00  149.00  163.00  219.00
                  16  23.00  103.00  208.00  225.00  292.00
                  32  23.00  188.00  342.00  354.00  418.00
                  64  22.90  258.00  397.00  416.00  491.00
                  128  22.90  344.00  473.00  494.00  573.00
                  256  22.90  506.00  645.00  622.00  672.00
                  512  22.90  527.00  598.00  794.00  779.00
                  1024  22.90  593.00  833.00  815.00  822.00
                  2048  22.90  773.00  853.00  801.00  834.00
                  4095  22.90  810.00  882.00  888.00  911.00
                  
                  0  22.90  0.00  13.00  17.00  33.00
                  1  22.90  4.00  39.00  45.00  77.00
                  2  22.90  13.00  61.00  70.00  108.00
                  4  22.90  33.00  91.00  101.00  149.00
                  8  22.90  65.00  168.00  180.00  232.00
                  16  22.90  113.00  234.00  250.00  311.00
                  32  22.90  183.00  327.00  343.00  409.00
                  64  22.90  259.00  402.00  419.00  492.00
                  128  22.90  365.00  509.00  527.00  585.00
                  256  22.90  427.00  533.00  736.00  715.00
                  512  22.90  527.00  600.00  810.00  794.00
                  1024  22.90  683.00  843.00  775.00  810.00
                  2048  22.90  699.00  796.00  867.00  897.00
                  4095  22.90  810.00  881.00  888.00  911.00
                  
                  0  22.90  0.00  12.00  15.00  34.00
                  1  22.90  4.00  37.00  43.00  74.00
                  2  22.90  13.00  62.00  71.00  109.00
                  4  22.90  31.00  98.00  108.00  154.00
                  8  22.90  60.00  149.00  163.00  218.00
                  16  22.90  102.00  202.00  276.00  325.00
                  32  22.90  166.00  289.00  308.00  382.00
                  64  22.90  242.00  369.00  392.00  485.00
                  128  22.90  333.00  456.00  475.00  607.00
                  256  22.90  423.00  531.00  735.00  716.00
                  512  22.90  563.00  646.00  641.00  708.00
                  1024  22.90  691.00  802.00  752.00  791.00
                  2048  22.80  698.00  808.00  871.00  898.00
                  4095  22.80  809.00  881.00  888.00  910.00
                  Note that the first bit on the LDR with 2 channels and additional resistors, is always between 2 and 4 on a basis of 1024 values, so we are talkling of a difference of 4.88 mV each bit, so around 9 mVpp in total. It could even be noise catched from the system as everything is floating without any shielding.

                  Comment


                  • #11
                    Very reminiscent of the now largely obsolete Vactrols, although some stocks are still around.

                    Anyway, I would not be surprised if there were a very large part to part tolerance. It's not mentioned in the datasheet and that can be a red flag.

                    Can I ask what ultimate objective is here? There might be other approaches that could be considered.
                    Last edited by nickb; 12-28-2017, 10:21 PM.
                    Experience is something you get, just after you really needed it.

                    Comment


                    • #12
                      Yes nickb, that's exaclty the purpose: have some substitutes of the old VTL5C1s as variable resistors.
                      Common digital pots are limited to some tens of voltages, while these can be also used as pots for tube amps' tonestacks.

                      I know the double LDR configuration (IIRC the Mesa Triaxis used them in that way) with the OPAMP, but it's not the way I would like to go.

                      I've found a solution to get an high resolution at low values and high values as well without wasting a second PWM output:
                      I add a 10k resistor in series with the led of the LCR (this gives me high resolution at high resistance values), and then I use a single output of the arduino to saturate a fet (or transistor, or whatever) in parallel with the 10k resistor to increase the resolution at lowest resistance values and decrease the minimum resistance as well. Basically we can imagine it as a "virtual" 13th bit, but it's way more: we can have 12 bit more of resolution where we need them (from 100 MOhm to 10 MOhm , from 10 MOhm to 1 MOhm, etc...) and then focus the "real" 12 bit on the lowest part of the resistance (where is more needed if we want to simulate log pots).

                      If it's not clear I can draw a schematic.

                      Comment


                      • #13
                        Good creative thinking.

                        Alternative approach is directly pwm-chopping the audio signal using analog switches. My favourite DG201B from Vishay is good up to 44Vpp and will switch fast enough to be PWM-ed with adequate resolution.
                        I guess hybrid approach to a standard tone stack would be possible too, i.e. bass and mid using DG201B switches and treble using LED->LDR opto. Just a thought.

                        P.S. A 70Vpp switches are available too: http://www.farnell.com/datasheets/20...224.1514498727

                        Comment


                        • #14
                          Originally posted by Roberto View Post
                          I've found a solution to get an high resolution at low values and high values as well without wasting a second PWM output:
                          I add a 10k resistor in series with the led of the LCR (this gives me high resolution at high resistance values), and then I use a single output of the arduino to saturate a fet (or transistor, or whatever) in parallel with the 10k resistor to increase the resolution at lowest resistance values and decrease the minimum resistance as well. Basically we can imagine it as a "virtual" 13th bit, but it's way more: we can have 12 bit more of resolution where we need them (from 100 MOhm to 10 MOhm , from 10 MOhm to 1 MOhm, etc...) and then focus the "real" 12 bit on the lowest part of the resistance (where is more needed if we want to simulate log pots).

                          If it's not clear I can draw a schematic.
                          Sort of a one bit exponent block floating point.

                          You didn't really say what the real reason is so I'll have to guess. You want to use them as linear devices and that implies you want some kind digital control, probably because you want to to store and recall settings in some fashion. Am I on the right lines here?

                          Yes, digipots are low voltage, but aside from a questionable desire to never put the signal thru anything other than a tube, what is so terribly wrong with attenuating and amplifying if necessary to make their use possible? These LCR devices are quite expensive and single sourced. You wouldn't need to have many before it make more sense cost wise to do it with opamps and digipots, or, dare I even say it, a DSP? And that's assuming you can overcome the tolerance issues. There's a reason Vactrols died out.
                          Experience is something you get, just after you really needed it.

                          Comment


                          • #15
                            Thank you darkfenriz, also for the tip for the DG201Bs.

                            I will try these LDRs and revert the results. Next step is to feed a PID on the PWM with an array of values, in order to get the right PWM (and the 2n3904 bit) value when the error between the target and the obtained resistance is below a fixed threshold.

                            Comment

                            Working...
                            X