การแก้ไขความสว่างที่ไม่ใช่เชิงเส้นใน LED เมื่อใช้ PWM


33

เมื่อขับ LED ด้วย PWM ความสว่าง (ตามที่ฉันรับรู้) ไม่ได้ปรับสเกลเชิงเส้นตามวัฏจักรหน้าที่ ความสว่างจะช้าลงเรื่อย ๆ จากนั้นเพิ่มทวีคูณตามรอบการทำงาน

ใครสามารถแนะนำกฎของหัวแม่มือที่จะใช้เป็นปัจจัยการแก้ไขหรือวิธีแก้ปัญหาอื่น ๆ ?


เมื่อฉันสร้างลิงค์ข้อมือ Knight Rider คู่หนึ่งฉันต้องใช้ x ^ 10 เพื่อทำให้สีซีดจางดูดี!
Rocketmagnet

3
คุณแน่ใจหรือไม่ว่า "ความสว่างเพิ่มขึ้นในขั้นต้นชี้แจงแล้วช้าลาดขึ้น"?
Dmitry Grigoryev

1
ฉันเชื่อว่าดวงตาของเราตอบสนองลอการิทึมอย่างชัดเจน
DKNguyen

คำตอบ:


13

สำหรับระดับ 16 มันง่ายที่จะทำตารางค้นหาง่าย ๆ "ด้วยมือ" และแปลงค่า 4 บิตในค่า 8 บิตเพื่อส่งไปยังตัวควบคุม PWM: นี่คือส่วนประกอบที่ฉันใช้ในโปรแกรมควบคุมอาเรย์นำ FPGA ของฉัน สำหรับคอนโทรลเลอร์ระดับ 8 บิตคุณจะต้องมีเอาต์พุตอย่างน้อย 11-12 บิตจากตารางค้นหา

library IEEE;
use IEEE.Std_logic_1164.all;

entity Linearize is
port ( reqlev : in std_logic_vector (3 downto 0) ;
    pwmdrive : out std_logic_vector (7 downto 0) );
    end Linearize;

architecture LUT of Linearize is
    begin
    with reqlev select
        pwmdrive <= "00000000" when "0000",
                    "00000010" when "0001",
                    "00000100" when "0010",
                    "00000111" when "0011",
                    "00001011" when "0100",
                    "00010010" when "0101",
                    "00011110" when "0110",
                    "00101000" when "0111",
                    "00110010" when "1000",
                    "01000001" when "1001",
                    "01010000" when "1010",
                    "01100100" when "1011",
                    "01111101" when "1100",
                    "10100000" when "1101",
                    "11001000" when "1110",
                    "11111111" when "1111",
                    "00000000" when others;
    end LUT;

ฉันกำลังพยายามหาว่าสูตรของคุณคืออะไร มันใกล้เคียงกับ f (x) = x ^ 2 อย่างมาก แต่ส่วนโค้งไม่ลึกพอ f (x) = x ^ 3/13 ทำให้ฉันเข้าใกล้ฉันมากขึ้น
ajs410

ไม่มีสูตร (ไม่ใช่เจตนา) ... ฉันป้อนค่าเริ่มต้นของเครื่องมือสร้างเส้นตรงด้วยการคาดเดาเพียง :-) จากนั้นฉันได้ขับเคลื่อนอาเรย์ขับคอลัมน์นำตามลำดับความสว่างและปรับแต่งค่าเพื่อให้ได้ทางลาดที่สม่ำเสมอ มันง่ายมากที่มีเพียง 16 ระดับ
Axeman

1
2n1

17

ในทางทฤษฎีแล้วมันควรจะเป็นแบบยกกำลัง แต่ฉันได้ผลลัพธ์ที่ดีที่สุดสำหรับการเฟดโดยใช้ฟังก์ชันกำลังสอง

ฉันก็คิดว่าคุณได้มันไปข้างหลัง ที่รอบหน้าที่ต่ำการเพิ่มความสว่างที่รับรู้นั้นใหญ่กว่ารอบหน้าที่เกือบเต็มซึ่งการเพิ่มความสว่างนั้นแทบจะมองไม่เห็น


ดูเพิ่มเติมแก้ไขแกมมา
starblue

17

ฉันได้รับการดูในเรื่องนี้ในช่วงไม่กี่วันที่ผ่านมาเนื่องจากฉันมีปัญหาเดียวกัน ... พยายามหรี่ไฟ LED โดยใช้ PWM ในลักษณะเชิงเส้นอย่างเห็นได้ชัด แต่ฉันต้องการความละเอียดขั้นตอนเต็ม 256 การพยายามเดาตัวเลข 256 เพื่อสร้างเส้นโค้งด้วยตนเองไม่ใช่เรื่องง่าย!

ฉันไม่ใช่นักคณิตศาสตร์ผู้เชี่ยวชาญ แต่ฉันรู้พอที่จะสร้างเส้นโค้งพื้นฐานด้วยการรวมฟังก์ชั่นและสูตรบางอย่างเข้าด้วยกันโดยไม่ทราบว่ามันทำงานอย่างไร ฉันพบว่าการใช้สเปรดชีต (ฉันใช้ Excel) คุณสามารถเล่นกับชุดตัวเลขตั้งแต่ 0 ถึง 255 ใส่สูตรไม่กี่สูตรในเซลล์ถัดไปและสร้างกราฟ

ฉันใช้แอสเซมเบลอร์ของ pic เพื่อทำสีซีดจางและคุณยังสามารถรับสเปรดชีตเพื่อสร้างรหัสแอสเซมเบลอร์ด้วยสูตร ( ="retlw 0x" & DEC2HEX(A2)) สิ่งนี้ทำให้ง่ายและรวดเร็วในการลองเส้นโค้งใหม่

หลังจากที่ได้เล่นกับฟังก์ชั่น LOG และ SIN โดยเฉลี่ยของทั้งสองและสิ่งอื่น ๆ อีกสองสามอย่างฉันก็ไม่ได้เส้นโค้งที่ถูกต้องจริงๆ สิ่งที่เกิดขึ้นคือส่วนกลางของจางหายไปช้ากว่าระดับล่างและระดับสูง นอกจากนี้หากเฟด - อัพทันทีตามด้วยเฟด - ดาวน์มีเข็มแหลมที่เห็นได้ชัดเจนในความเข้ม สิ่งที่จำเป็น (ในความคิดของฉัน) เป็นเส้นโค้ง S

การค้นหาวิกิพีเดียอย่างรวดเร็วเกิดขึ้นกับสูตรที่จำเป็นสำหรับเส้นโค้ง S ฉันเสียบสิ่งนี้ลงในสเปรดชีตของฉันและทำการปรับเปลี่ยนเล็กน้อยเพื่อให้ทวีคูณข้ามช่วงค่าของฉันและมากับสิ่งนี้:

เอสโค้ง

ฉันทดสอบมันบนอุปกรณ์ของฉันและมันก็ทำงานได้อย่างสวยงาม

สูตร Excel ที่ฉันใช้คือ:

=1/(1+EXP(((A2/21)-6)*-1))*255

โดยที่ A2 คือค่าแรกในคอลัมน์ A ซึ่งเพิ่ม A3, A4, ... , A256 สำหรับแต่ละค่า

ฉันไม่รู้ว่านี่ถูกต้องทางคณิตศาสตร์หรือไม่ แต่มันให้ผลลัพธ์ที่ต้องการ

นี่คือชุดเต็มของ 256 ระดับที่ฉันใช้:

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B,
0x0C, 0x0C, 0x0D, 0x0D, 0x0E, 0x0F, 0x0F, 0x10, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x26, 0x27, 0x29, 0x2B, 0x2C,
0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x43, 0x45, 0x47, 0x4A, 0x4C, 0x4F,
0x51, 0x54, 0x57, 0x59, 0x5C, 0x5F, 0x62, 0x64, 0x67, 0x6A, 0x6D, 0x70, 0x73, 0x76, 0x79, 0x7C,
0x7F, 0x82, 0x85, 0x88, 0x8B, 0x8E, 0x91, 0x94, 0x97, 0x9A, 0x9C, 0x9F, 0xA2, 0xA5, 0xA7, 0xAA,
0xAD, 0xAF, 0xB2, 0xB4, 0xB7, 0xB9, 0xBB, 0xBE, 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
0xD0, 0xD2, 0xD3, 0xD5, 0xD7, 0xD8, 0xDA, 0xDB, 0xDD, 0xDE, 0xDF, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5,
0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2,
0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF8,
0xF9, 0xF9, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC,
0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD,
0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF

สมการนี้ใช้ได้อย่างสมบูรณ์แบบสำหรับฉัน
Ignacio Vazquez-Abrams


4

ฉันใช้ ATtiny เพื่อส่องสว่างที่ดาดฟ้าของฉัน ความสว่างถูกควบคุมโดยใช้หม้อเชื่อมต่อกับขา ADC

ฟังก์ชั่นเลขชี้กำลังพยายามและเอาท์พุท PWM ตามที่ดูเหมือนว่าจะให้เพิ่มขึ้นเชิงเส้นในการรับรู้ความสว่าง

ฉันใช้สูตรนี้:

out = pow(out_max, in/in_max)

Attiny85 @ 8MHz ใช้เวลาประมาณ 210us ในการคำนวณข้างต้น เพื่อปรับปรุงประสิทธิภาพการทำตารางการค้นหา เนื่องจากอินพุตนั้นมาจากหน่วยความจำ ADC ขนาด 10 บิตและ ATtiny มี จำกัด ฉันจึงต้องการสร้างตารางที่สั้นกว่าเช่นกัน

แทนที่จะสร้างตารางการค้นหาที่มี 1024 รายการให้สร้างตารางการค้นหาแบบย้อนกลับที่มี 256 รายการ (512 ไบต์) ในหน่วยความจำโปรแกรม (PGMEM) ฟังก์ชันถูกเขียนเพื่อทำการค้นหาแบบไบนารีบนตารางนั้น วิธีนี้ใช้เวลา 28uS ต่อการค้นหาแต่ละครั้งเท่านั้น ถ้าฉันใช้ตารางการค้นหาโดยตรงมันจะต้องมีหน่วยความจำ 2kb แต่การค้นหาจะใช้เวลาเพียง 4uS หรือมากกว่านั้น

ค่าที่คำนวณได้ในตารางการค้นหาใช้ช่วงอินพุต 32-991 เท่านั้นโดยทิ้งช่วงล่าง / บนของ ADC ในกรณีที่เกิดปัญหากับวงจร

ด้านล่างเป็นสิ่งที่ฉันมีตอนนี้

// โปรแกรมทดสอบ anti_log

/ * LED เชื่อมต่อกับ PIN6 (PB1) * /
#define LED 1 

// ตารางค้นหา Anti-Log (ย้อนกลับ) 
// y = 0-255 (เอาต์พุต pwm), y_range = 256
// x = 0-1023 (อินพุต ADC 10 บิต); 
// สมมติว่าค่า ADC out ที่ต่ำกว่า / สูงกว่าไม่สามารถใช้งานได้
// ยกเลิกค่า 32 แรกและ 32 ค่าสุดท้าย
// min_x = 32, max_x = 1023-min_x, x_range = 1024-2 * min_x
// ANTI_LOG [y] = รอบ (บันทึก x_range * (y, ฐาน = y_range) + min_x)
// ให้ค่าเป็น x ทำการค้นหาแบบไบนารีบนตารางด้านล่าง
// ใช้เวลาประมาณ 28uS สำหรับนาฬิกา Attiny85 @ 8MHz
PROGMEM prog_uint16_t ANTI_LOG [] = {
  0x0000, 0x0020, 0x0098, 0x00de, 0x0110, 0x0137, 0x0156, 0x0171, 0x0188, 0x019c, 0x01af, 0x01bf, 0x01c9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9
  0x0200, 0x020a, 0x0214, 0x021e, 0x0227, 0x022f, 0x0237, 0x0237, 0x0246, 0x0244, 0x0254, 0x025b, 0x0261,
  0x0278, 0x027d, 0x0282, 0x0288, 0x028c, 0x0291, 0x0296, 0x0296, 0x029f, 0x02a7, 0x02a7, 0x02ab3, 0x02b3, 0x02b3, 0x02b3, 0x028a
  0x02be, 0x02c2, 0x02c5, 0x02c9, 0x02ccf, 0x02cf, 0x02d3, 0x02d6, 0x02d9, 0x02dc, 0x02e2, 0x02e5, 0x02e8, 0x02e8, 0x02e8, 0x02e5, 0x02e8, 0x02e8, 0x02e8, 0x02e5, 0x02e8, 0x02e8, 0x02e5, 0x02e8, 0x02e8, 0x02e8, 0x02e8, 0x02e8, 0x02e8
  0x02f0, 0x02f3, 0x02f5, 0x02f8, 0x02fa, 0x02fd, 0x0300, 0x0302, 0x0307, ​​0x0309, 0x030b, 0x030b, 0x030b, 0x0330, 0x030b
  0x0317, 0x0319, 0x031b, 0x031d, 0x031f, 0x0321, 0x0323, 0x0323, 0x0332, 0x0329, 0x032d, 0x032f, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321, 0x0321
  0x0336, 0x0338, 0x033a, 0x033c, 0x033d, 0x033f, 0x0341, 0x0341, 0x0344, 0x0346, 0x0349, 0x0334, 0x034b, 0x034c, 0x033c
  0x0351, 0x0352, 0x0354, 0x0355, 0x0357, 0x0358, 0x0355, 0x0351, 0x0351, 0x0351, 0x0361, 0x0361, 0x0361, 0x0364, 0x0364, 0x0354, 0x0354, 0x0354, 0x0354, 0x0354, 0x0354, 0x0354, 0x0364
  0x0368, 0x0369, 0x036b, 0x036c, 0x036d, 0x036f, 0x0370, 0x0371, 0x0372, 0x0376, 0x0376, 0x0376, 0x0376, 0x0376, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379, 0x0379
  0x037c, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0383, 0x0386, 0x0388, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389, 0x0389
  0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x039a, 0x039a, 0x039a, 0x039a, 0x039a, 0x039a, 0x039c, 0x039c, 0x039c, 0x039c, 0x039c, 0x039c, 0x039c, 0x039c, 0x039c, 0x039
  0x039f, 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a9, 0x03a9, 0x03a9, 0x03a, 0x03a, 0x03a, 0x03a9, 0x03a9, 0x03a9, 0x03a9, 0x03a9, 0x03a9, 0x03a9, 0x03a9, 0x03a9
  0x03ae, 0x03af, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b4, 0x03b5, 0x03b7, 0x03b8, 0x03b8, 0x03b8, 0x03b8, 0x03b8, 0x03b8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8, 0x03B8
  0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03bf, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c5, 0x03c5, 0x03c5, 0x03c7, 0x03c7, 0x03c7, 0x03c5, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7, 0x03c7
  0x03c9, 0x03ca, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03cd, 0x03ce, 0x03cf, 0x03d0, 0x03d1, 0x03d1, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3, 0x03d3
  0x03d5, 0x03d6, 0x03d6, 0x03d7, 0x03d8, 0x03d8, 0x03d9, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd, 0x03dd
};

// ค้นหาแบบไบนารีโดยใช้ตารางด้านบน
ไบต์ antilog (int x)
{
  ไบต์ y = 0x80
  int av;
  สำหรับ (int i = 0x40; i> 0; i >> = 1)
  {
    av = pgm_read_word_near (ANTI_LOG + y);
    ถ้า (av> x)
    {
      y - = i;
    }
    อื่นถ้า (av <x) 
    {
      y | = i;
    }
    อื่น
    {
      ส่งคืน y
    }
  }
  ถ้า (pgm_read_word_near (ANTI_LOG + y)> x)
  {
    y - = 1;
  }
  ส่งคืน y
}


การตั้งค่าเป็นโมฆะ ()
{
  pinMode (LED, OUTPUT);
  digitalWrite (LED, LOW);
}

#define MIN_X 0
#define MAX_X 1024

เป็นโมฆะห่วง ()
{
  int i;
  // antilog_drive
  สำหรับ (i = MIN_X; i <MAX_X; i ++)
  {
    analogWrite (LED, antilog (i));
    ล่าช้า (2);
  }
  สำหรับ (--i; i> = MIN_X; i--)
  {
    analogWrite (LED, antilog (i));
    ล่าช้า (2);
  }
  ล่าช้า (1,000);
  // ไดรฟ์เชิงเส้น
  สำหรับ (i = MIN_X; i <MAX_X; i ++)
  {
    analogWrite (LED, i >> 2);
    ล่าช้า (2);
  }
  สำหรับ (--i; i> = MIN_X; i--)
  {
    analogWrite (LED, i >> 2);
    ล่าช้า (2);
  }
  ความล่าช้า (2000);
}

1

PDF นี้อธิบายเส้นโค้งที่ต้องการซึ่งเห็นได้ชัดว่าเป็นลอการิทึม หากคุณมีเครื่องหรี่แสงเชิงเส้น (ค่า PWM ของคุณ) ฟังก์ชันควรเป็นลอการิทึม

ที่นี่คุณสามารถค้นหาตารางสำหรับความสว่าง 32 ขั้นตอนสำหรับ 8 บิต PWM

ที่นี่สำหรับ 16 ขั้นตอน


1

นี่คือสิ่งที่ฉันได้ทำขึ้นอยู่กับว่าการตอบสนองของฟอรั่ม Arduino ฉันคำนวณค่าจาก 0 ถึง 255 ดังนั้นมันจึงใช้งานง่ายด้วย pwm บน arduino

byte ledLookupTable[] = {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,23,23,24,24,25,26,26,27,28,28,29,30,30,31,32,32,33,34,35,35,36,37,38,38,39,40,41,42,42,43,44,45,46,47,47,48,49,50,51,52,53,54,55,56,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,91,92,93,94,95,97,98,99,100,102,103,104,105,107,108,109,111,112,113,115,116,117,119,120,121,123,124,126,127,128,130,131,133,134,136,137,139,140,142,143,145,146,148,149,151,152,154,155,157,158,160,162,163,165,166,168,170,171,173,175,176,178,180,181,183,185,186,188,190,192,193,195,197,199,200,202,204,206,207,209,211,213,215,217,218,220,222,224,226,228,230,232,233,235,237,239,241,243,245,247,249,251,253,255};

จากนั้นให้ใช้กับ Arduino เพียงทำเช่นนั้น:

analogWrite(ledPin, ledLookupTable[brightness]); //with brighness between 0 and 255

หวังว่ามันจะเป็นประโยชน์สำหรับบางคน;)


1

ฉันกำลังจัดการกับเรื่องนี้และฉันใช้วิธีที่แตกต่างกันเล็กน้อย ฉันต้องการความสว่าง 256 ระดับ แต่การจับคู่ช่วง 0-255 เชิงเส้นกับช่วงที่ไม่ใช่เชิงเส้น 0-255 จบลงอย่างที่คุณเห็นในคำตอบอื่น ๆ ที่มีรายการซ้ำกันมากมาย (เช่นค่าอินพุตหลายค่าของคุณส่งผลให้ระดับความสว่างเท่ากัน)

ฉันพยายามปรับเปลี่ยนอัลกอริทึมเพื่อแมปช่วงอินพุต 0-256 กับช่วงเอาต์พุต 0-1023 แต่ถึงแม้ว่าจะมีการแมปค่าหลายค่าเป็น 0 ดังนั้นฉันจึงลองทำบางอย่างที่แตกต่างออกไปเล็กน้อย - ฉันใช้ระดับ 0-255 เพื่อสร้างค่าที่ไม่ใช่เชิงเส้นในช่วง 0-769 (นั่นคือ 1023 ลบ 255) โดยใช้sin()แล้วเพิ่มเข้าไปในระดับอินพุตเพื่อรับเอาต์พุตในช่วง 0-1023 โดยไม่มีการซ้ำซ้อน ฉันจะกำหนดค่าตัวจับเวลาให้ใช้ตัวนับ 1,023 และตั้งตัวเปรียบเทียบสำหรับเอาต์พุต PWM เป็นค่าจากตารางการค้นหาตามระดับแสงที่ฉันต้องการ (0-255)

นี่คือโปรแกรม C ที่ฉันใช้สร้างตารางการค้นหาของฉัน:

#include <stdio.h>
#include <math.h>

int main() {
    int i;
    double j;
    int k;

    printf( "int brightness[] = {\n" );
    for( i=0; i<256; i++ ) {
        // 0 - 255 => 1.0 - 0.0, multiply by 90 degrees (in radians)
        j = (1 - (i / 255.0)) * M_PI / 2;
        j = sin( j );
        k = (1023-255) - j * (1023-255);
        printf( "%s%d%s%s",
                (((i % 8) == 0) ? "    " : " "), // leading space at start of line
                k+i,
                ((i < 255) ? "," : ""),          // comma after all but last value
                (((i % 8) == 7) ? "\n" : "")     // line break every 8 items
              );
    }
    printf( "  };\n" );
}

และนี่คือตาราง:

int brightness[] = {
    0, 1, 2, 3, 4, 5, 6, 7,
    8, 10, 11, 12, 14, 15, 16, 18,
    19, 21, 22, 24, 25, 27, 29, 30,
    32, 34, 35, 37, 39, 41, 43, 44,
    46, 48, 50, 52, 54, 56, 58, 61,
    63, 65, 67, 69, 72, 74, 76, 78,
    81, 83, 86, 88, 91, 93, 96, 98,
    101, 103, 106, 109, 111, 114, 117, 120,
    122, 125, 128, 131, 134, 137, 140, 143,
    146, 149, 152, 155, 158, 161, 164, 168,
    171, 174, 177, 181, 184, 187, 191, 194,
    198, 201, 205, 208, 212, 215, 219, 222,
    226, 230, 233, 237, 241, 244, 248, 252,
    256, 260, 263, 267, 271, 275, 279, 283,
    287, 291, 295, 299, 303, 307, 312, 316,
    320, 324, 328, 333, 337, 341, 345, 350,
    354, 358, 363, 367, 372, 376, 381, 385,
    390, 394, 399, 403, 408, 412, 417, 422,
    426, 431, 436, 440, 445, 450, 455, 459,
    464, 469, 474, 479, 484, 489, 493, 498,
    503, 508, 513, 518, 523, 528, 533, 538,
    543, 548, 554, 559, 564, 569, 574, 579,
    584, 590, 595, 600, 605, 610, 616, 621,
    626, 632, 637, 642, 647, 653, 658, 664,
    669, 674, 680, 685, 690, 696, 701, 707,
    712, 718, 723, 729, 734, 740, 745, 751,
    756, 762, 767, 773, 778, 784, 790, 795,
    801, 806, 812, 818, 823, 829, 834, 840,
    846, 851, 857, 863, 868, 874, 880, 885,
    891, 897, 902, 908, 914, 920, 925, 931,
    937, 942, 948, 954, 960, 965, 971, 977,
    982, 988, 994, 1000, 1005, 1011, 1017, 1023
};

ฉันอาจจะตรวจสอบฟังก์ชั่นอื่น ๆ (เช่นlog()) เมื่อฉันเริ่มใช้งานได้แล้ว


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.