Stránka 1 z 1

Měření napětí v Bascomu

Napsal: 16 zář 2015, 16:55
od denny_ul
Poradí někdo s programem na indikátor napětí dle následujícího schéma?
LED by se měli postupně rosvěcet dle určitých úrovní napětí na baterii.
Napětí z děliče na vstup PB0, výstupy LED na PB1-4

Napsal: 16 zář 2015, 17:18
od nekmil
PB.0 není vstupem AD převodníku.
Můžeš použít PB.5(nebude možný Reset tudíž ani další programování) !!!
PB.4, PB.3, PB.2

Napsal: 16 zář 2015, 18:16
od frpr666
@nekmil Přesně tak na PB0 není připojen ADC.
@denny_ul
můžeš prohodit vstupy PB0 a PB4. Na PB0 si pověs tu LED diodu a na PB4 si dej ten analogový vstup. Program by mohl být takto:

Kód: Vybrat vše

// file: main.c
// podle hodnoty na ADC2 nahazuje ledky na výstupech PB0,PB1,PB2,PB3
// odzkouseno: n*/y
//
// todo: definovat funkce:
// void io_setup( void);
// void ad_setup( void);
// uint16_t ad_read_ch2( void);

#define AD_LIMIT0 (uint16_t)((1024/5)*1)
#define AD_LIMIT1 (uint16_t)((1024/5)*2)
#define AD_LIMIT2 (uint16_t)((1024/5)*3)
#define AD_LIMIT3 (uint16_t)((1024/5)*4)

void setup( void)
{
  io_setup();
  ad_setup();
}

void loop( void)
{
  uint16_t ad_value;
  uint8_t output;

  ad_value = ad_read_ch2();

  output = 0;
  if (ad_value > AD_LIMIT3)
  {
    output = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); //PB0,PB1,PB2,PB3 on
  }
  else if (ad_value > AD_LIMIT2)
  {
    output = (1 << 0) | (1 << 1) | (1 << 2); //PB0,PB1,PB2 on
  }
  else if (ad_value > AD_LIMIT1)
  {
    output = (1 << 0) | (1 << 1); //PB0,PB1 on
  }
  else if (ad_value > AD_LIMIT0)
  {
    output = (1 << 0); //PB0 on
  }
  PORTB = output;
}

void main( void)
{
  setup();
  for(;;)
  {
    loop();
  }
}
// EOF

Napsal: 16 zář 2015, 18:33
od denny_ul
Tak to jsem přehlédl, dík.
Takže změna, vstup PB4 a výstupy PB0-3
Nebyl by program v Bascomu?

Napsal: 16 zář 2015, 21:18
od Ruprecht
V Bascomu bude program hodně podobný tomu pro RC spínač.
Na začátku by mělo být
CONFIG ADC = single, PRESCALER = AUTO, REFERENCE = AVCC nebo INTERNAL (viz help).
Vstupní napětí je pak čteno AD převodníkem tak, že vstupních 0V je ADC hodnota = 0, vstupní napětí o velikosti reference je 1023. Od toho je tam ten vstupní dělič R1-R2. Tiny 13 umí nakonfigurovat vnitřní referenci 1,1V nebo napájecí napětí. Vstupní dělič by měl při vstupních 12V na JP1 pustit na nohu ADC 5V při referenci AVCC (5V) nebo 1,1V (při referenci INTERNAL), raději trochu míň. Pak při 5V referenci jeden každý bit znamená napětí 5V/1024bit = asi 4,88mV. Když ADC načte hodnotu třeba 280, na vstupu je asi 1,37V (280*4,88mV).

Hodnota ADC je v základu desetibitová, takže
dim hodnota as word

a pak v hlavní smyčce (do...loop)
hodnota = getadc(3)
(neboli čtení ADC3, který je zrovna na pinu PB3)

No a ta hodnota se pak porovná (třeba Select case, nebo sérií ifů) a podle toho si aktivuješ výstupy (set portb.3 neboli portb.3 = 1) a rozsvítíš LEDky

Napsal: 16 zář 2015, 22:03
od denny_ul
Ten program bude tedy začínat takto:

Kód: Vybrat vše

$regfile = "attiny13a.dat"
$crystal = 9600000
$hwstack = 10
$swstack = 8
$framesize = 16

Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output
Config Portb.3 = Output

Led1 Alias Portb.0
Led2 Alias Portb.1
Led3 Alias Portb.2
Led4 Alias Portb.3

Dim V As Word

Config Adc = Single , Prescaler = Auto , Reference = Avcc

Do

Start Adc
V = Getadc(2)
Stop Adc


Loop

a pak bude vyhodnocení toho co se má v které úrovni sepnout.

V tomto kodu "V= Getadc(2)" ta "(2)" znamená že je to ADC2 tj. PB4?

Napsal: 16 zář 2015, 22:13
od Ruprecht
Start ADC a Stop ADC není potřeba, převod se nastartuje tím configem a může dál běžet, ničemu to nevadí (koukej do helpu: Start Adc ' NOT required since it will start automatic).
Pak už jenom spočíst vstupní dělič z 12V na 5V a dopsat podmínky pro rozsvícení ledek.

Pokud hodnota ADC bude "poskakovat" (což bude, mohou problikávat LEDky poblíž rozhodovacích úrovní), omezí se to kodenzátorem paralelně k R2), nebo průměrováním hodnot ADC z několika čtení, případně zmenšením bitového rozlišení převodníku (pro vyhodnocení třech úrovní nepotřebuješ 1024 hodnot, bohatě stačí třeba 256. Takže po getadc() tu načtenou hodnotu vydělíš čtyřma V=V/4. To je nejjednodušší řešení)