PWM vezérlés RS485 buszon át

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3320
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

HozzászólásSzerző: kapu48 » 2012. szeptember 28. péntek, 15:24

Van az csak keresni kel!

include-file init_benbus.inc
27. sor: Dim Type As String * 6

:lol:

Avatar
zb83
Biztosítékgyilkos
Hozzászólások: 69
Csatlakozott: 2008. október 24. péntek, 6:00

HozzászólásSzerző: zb83 » 2012. szeptember 28. péntek, 15:55

Jaaa hát én csak a bemásolt kódban keresgéltem. Annyira azért nem érek rá. :)

Avatar
tetye
Chipgyilok
Hozzászólások: 279
Csatlakozott: 2007. augusztus 29. szerda, 6:00
Tartózkodási hely: Perbál
Kapcsolat:

HozzászólásSzerző: tetye » 2012. szeptember 28. péntek, 16:25

Hát ma kicsit ollózgattam és az eredmény a sikeres kommunikáció lett.
CRC16 ot kellene számoljak valahogy a master oldalon de ott VisualBasic6 van még ebben szeretnék segítséget kérni mert gugli most épp nem a barátom legalábbis amiket találtam mintákat azok nem nagyon állnak közel a várt értékekhez. Illetve lenne még 1 dolog, PC ventillátor fordulatszámát szeretném szabályozni(hőfok fügvényében), és lekérdezni(rs485).
Szabad lábak még az int0 , adc0,1,7 , oca1a , icp1a
A kódom ami sikeres lett eddig:

Kód: Egész kijelölése

$regfile = "m8def.dat"
$crystal = 11059200
$baud = 19200
Config Sda = Portc.4
Config Scl = Portc.5
Config Serialin = Buffered , Size = 64 , Bytematch = 10
Enable Interrupts
Echo Off

Const Master = "00"
Dim Slave As String * 2
Slave = "01"
Const Namee = "ARA600"
Const Sep = "#"

Dim Rpmmsb As Byte
Dim Tempmsb As Byte
Dim Templsb As Byte
Dim S_cmd As String * 20
Dim S_val As String * 20
Dim S_slave As String * 2
Dim Tmp_line As String * 255
Dim Chk As String * 4
Dim Chk_a As Integer
Dim Chk_c As Byte
Dim Chk_line As String * 255
Dim Homero As String * 7
Dim Speed As String * 8
Dim Olvas As Byte
Dim Chkstart As String * 1
Dim Dd As String * 2
Dim Ddh As String * 2
Dim Error As Byte
Dim Flag As Byte
Dim Tel As Integer
Dim Teltmp As Integer
Dim Tmp As String * 1
Dim Ss As String * 2
Dim G_cmd As String * 20
Dim S_chk As String * 4
Dim G_val As String * 20
Dim Ge_val As String * 20
Dim Tmp_cmd As String * 20
Dim Cik As Byte
Dim Tmp_cik As Byte
Dim Tmp_cikk As Byte

Declare Sub Send_line(byval Slave As String , Byval S_cmd As String , Byval S_val As String)
Declare Sub Checksumm(chk_line As String)
Declare Sub Readtemp(tempmsb As Byte)
Declare Sub Readrpm(rpmmsb As Byte)
Declare Sub Startconvert()
Declare Sub Get_line(tmp_line As String , Flag As Byte , Error As Byte)
Declare Sub Getval(g_cmd As String)

Olvas = 0

'******** Main program **************************
Call Startconvert
Reset Portd.3
Do
 If Olvas > 0 Then                                          'Ha érkezett $10 az UARTra akkor ugrás a rutinra
   Gosub Rs485cmd
 End If
Loop
'******** end main program **********************
End

Rs485cmd:                                                   'Ez már a BenBus része
'Print "getline"
Call Get_line(tmp_line , Flag , Error)
'Reset Watchdog                                              'töröljük az UART IN buffert
'Clear Serialin
'Csak hibakeresésre
'Print "Get_line :" ; Tmp_line ; "  F:" ; Flag ; "  E:" ; Error
'Print "Chk :" ; Chk
' Flag = 1, ha a csomag hibátlan, elválasztó jelek a helyükön vannak és az ellenőrző összeg OK
' G_cmd változóba kerül be a master által küldött parancs
' G_val változóba kerül be a master által küldött érték
' 3 = ellenőrző összeg hiba
' 4 = slave nem válaszol
' 5 = nyitó karakter hibás
' 6 = elválasztó karakter 1 nem jó
' 7 = elválasztó karakter 2 nem jó
' 8 = elválasztó karakter 3 nem jó
' 9 = zárókarakter hibás
   If Flag = 1 Then
         Select Case G_cmd
            Case "[PING]" : Call Send_line(slave , Namee , "PONG" )
            Case "[GET]" :
             Select Case G_val
                  Case "TEMP" :
                     Call Readtemp(tempmsb)
                     Call Send_line(slave , "[Temp]" , Homero)
                  Case "FANS" :
                     Call Readrpm(rpmmsb)
                     Call Send_line(slave , "[Fans]" , Speed)
                  Case Else :                               'Ismeretlen, vagy nem feldolgozott a g_val értéke
                  Call Send_line(slave , "unknow value" , G_val)       'ezért unknow választ küldünk masternak
             End Select

            Case Else:
               Call Send_line(slave , G_cmd , "unknow cmd") 'ismeretlen parancsra válasz a masternak
         End Select
   End If
Clear Serialin                                              'UART IN buffer törlése
Olvas = 0
Return

'******** start convert *************************
Sub Startconvert()
I2cstart
I2cwbyte &H90
I2cwbyte &HEE
I2cstop
End Sub
'************************************************

'******** read temperature **********************
Sub Readtemp(tempmsb As Byte)
'-------------
I2cstart
I2cwbyte &H90                                               'send adress byte
I2cwbyte &HAA                                               'send register byte
I2cstop

I2cstart
I2cwbyte &H91                                               'read register
I2crbyte Tempmsb , Ack
I2crbyte Templsb , Nack
I2cstop
Tempmsb = Tempmsb - 3
Homero = Str(tempmsb)                                       'homero változóba összeállítjuk a visszakapott adatokat
Homero = Homero + ","
Homero = Homero + Str(templsb)
Homero = Homero + "C"
End Sub Readtemp
'************************************************

'******** read rpm ******************************
Sub Readrpm(rpmmsb As Byte)
'-------------ide kellene a ford. szám mérés
Speed = "1260"
Speed = Speed + "Rpm"
End Sub Readrpm
'************************************************

'************************************************
Serial0charmatch:
   Olvas = 1
Return
'************************************************

'************************************************
Sub Send_line(byval Slave As String , Byval S_cmd As String , Byval S_val As String)
 Portd.3 = 1
   Tmp_line = "{" + Master + Sep + Slave + Sep + S_cmd + "[" + S_val + "]" + Sep
   Call Checksumm(tmp_line)
   Tmp_line = Tmp_line + Chk + "}" : Print Tmp_line : Tmp_line = " "
   Waitms 100
 Portd.3 = 0
End Sub Send_line
'************************************************

'************************************************
Sub Checksumm(chk_line As String)
Chk_c = Len(chk_line)
Chk_a = Crc16(chk_line , Chk_c)
Chk = Hex(chk_a)
End Sub
'************************************************

'************************************************
Sub Get_line(tmp_line As String)
Error = 0
Flag = 1
       'slave
       Input Tmp_line                                       ' no timeout
Chkstart = Left(tmp_line , 1)
If Chkstart = "{" Then
Dd = Mid(tmp_line , 2 , 2)
   If Dd = Slave Or Dd = "99" Then
      If Tmp_line = "" Then
         Error = 4 : Flag = 0
         Else
         Tel = Len(tmp_line) : Tmp = Left(tmp_line , 1)
         If Tmp = "{" Then
            Tmp = Mid(tmp_line , 4 , 1)
                        If Tmp = Sep Then
               Tmp = Mid(tmp_line , 7 , 1)
               If Tmp = Sep Then
                  Teltmp = Tel - 5 : Tmp = Mid(tmp_line , Teltmp , 1)
                  If Tmp = Sep Then
                     Tmp = Right(tmp_line , 1)
                        If Tmp = "}" Then
                           Dd = Mid(tmp_line , 2 , 2)
                              If Dd <> Slave And Dd <> "99" Then Flag = 0
                           Ss = Mid(tmp_line , 5 , 2) : Teltmp = Tel - 13 : G_cmd = Mid(tmp_line , 8 , Teltmp)
                           Teltmp = Tel - 4 : S_chk = Mid(tmp_line , Teltmp , 4)
                           G_val = ""
                           Ge_val = ""
                           Call Getval(g_cmd)
                           If Len(g_val) > 0 Then
                              G_cmd = Tmp_cmd
                              Ge_val = "[" + G_val + "]"
                           End If
                             If Dd = "99" Then
                                 Ddh = "99"
                                 Else
                                 Ddh = Slave
                              End If
                              Tmp_line = "{" + Ddh + Sep + Master + Sep + G_cmd + Ge_val + Sep
                           Call Checksumm(tmp_line)
                           Tmp_line = Tmp_line + Chk + "}"
                           If Chk <> S_chk Then
                            Error = 3 : Flag = 0
                           End If
                         Else
                           Error = 9 : Flag = 0
                        End If
                   Else
                     Error = 8 : Flag = 0
                  End If
                Else
                  Error = 7 : Flag = 0
               End If
             Else
               Error = 6 : Flag = 0
            End If
          Else
            Error = 5 : Flag = 0
         End If
      End If
      If Flag = 0 Then G_cmd = ""
   Else
   Flag = 0
   End If
   Else
   Flag = 0
End If
End Sub
'
'*********************************************************************************

'*********************************************************************************
Sub Getval(g_cmd As String)
   Tmp_cik = Len(g_cmd) - 1                                 ' g_cmd hossza-1
   Tmp_cikk = Tmp_cik + 1                                   ' g_cmd hossza
   For Cik = 2 To Tmp_cik Step 1                            ' végégmegyünk g_cmd-n
      Tmp_cmd = Mid(g_cmd , Cik , 1)                        'kivágunk egy karaktert
      If Tmp_cmd = "[" Then Tmp_cikk = Cik                  'ha "[" akkor megjegyezzük a pozicióját
    Next Cik
   Cik = Tmp_cikk                                           'cik egyenlő a "["pozíciójával
   Incr Cik                                                 'cik +1 átugorjuk a "[" zárójelet
   If Cik < Tmp_cik Then                                    'ha cik még kiebb mint a g_cmd hossza akkor
      Tmp_cikk = Tmp_cik - Cik                              'vége - eleje = hossz
      Incr Tmp_cikk
      If Tmp_cikk >= 1 Then
         G_val = Mid(g_cmd , Cik , Tmp_cikk)
         Decr Cik
         Decr Cik
        Tmp_cmd = Mid(g_cmd , 1 , Cik)
      End If
   End If
End Sub
'*********************************************************************************

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9989
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 29. szombat, 6:36

oc1a: pwm1a kimenete....
Innen sima pwm-l fordulatszámszabályzol. Ha visszajelzés van, azt INT lábra tedd.

Avatar
tetye
Chipgyilok
Hozzászólások: 279
Csatlakozott: 2007. augusztus 29. szerda, 6:00
Tartózkodási hely: Perbál
Kapcsolat:

HozzászólásSzerző: tetye » 2012. október 1. hétfő, 9:46

Kipróbáltam, így most működik, de csak ledet tettem rá.

Kód: Egész kijelölése

'PWM
Config Timer1 = Pwm , Prescale = 256 , Compare A Pwm = Clear Down
Enable Timer1
Start Timer1
Config Portb.1 = Output
Dim Pwm_a As Byte   


Kód: Egész kijelölése

Pwm1a = 0

Do

For Pwm_a = 1 To 255
Pwm1a = Pwm_a
Pwm_a = Pwm_a + 1
Waitms 10
Next Pwm_a

 Loop


Milyen megoldást lehetne kitalálni hogy a pc ventit tudja szabályozni?
Szerintem a + ágba kellene valamit beiktatni, mert a gndnek fixnek kellene lennie a benne lévő fordulatszám mérő miatt.
Vagy annak a + kell hogy fix legyen(valahol ilyet is olvastam)?
Hogy működhet ez?
Arra milyen csatolást lehetne csinálni? Gondoltam 1k val felhuzom + ra az int0 lábat teszek rá egy 5,1v -os zenert és a venti jeladó lábát. Ez így jó lehet?
Pwm kimenetre pedig egy npn és egy pnp fet ?

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9989
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. október 1. hétfő, 10:05

Hülye tipp:
- tranzisztor, akár a gnd fele is, és innentől a ventillátor megy a kollektorkörbe. Itt kondival simítani a lüktetést.
- Optocsatolóval :P jelfordítást végezni. Vagy simán hajts meg egy tranzisztoros forídtóval egy P-FET-et (+ ág szaggatás).
- műveleti erősítővel PWM-> analóg jel -> erősítés
- kapcsolóüzemű táp, szabályzott visszacsatoló körrel...

Megyek pihenni :) ...


Mintha Sirleslie valamelyik évi versenyre küldött volna be ilyen szabályozást Tiny13 alapúal...


Az INT az jó. Amire vigáyzz: GND-ne szaggass a ventillátornál, mert az azonnal INTet generál :). A venti kimeneti láb ra soros ellenállás (1k...3k3), és a AVRláb-GND közé 5V1 zener.

Avatar
tetye
Chipgyilok
Hozzászólások: 279
Csatlakozott: 2007. augusztus 29. szerda, 6:00
Tartózkodási hely: Perbál
Kapcsolat:

HozzászólásSzerző: tetye » 2012. október 1. hétfő, 14:13

Ez a kapcsolás jó lehet nekem?(7805 háttal :P)
Kép
A hozzászólást 1 alkalommal szerkesztették, utoljára tetye 2012. október 1. hétfő, 16:03-kor.

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 894
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2012. október 1. hétfő, 14:21

Az az 560 ohm kicsi lesz, jó oda is 10k, a PNP -NPN közé meg mondjuk 4.7kk, mert az első kapcsolásnál kiég a PNP B-E diódája. A nyitáshoz 0.6V elég meg a vezérelt áram/béta kb.
JAni

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9989
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. október 1. hétfő, 14:44

A Végén a 4148 nem kellene a ventillátor által a fordított polaritással párhuzamosan? Hátha motorként akarna működni és ne táplálja meg az áramkört. Bár legutóbb a szétszedett az belül elektrokius volt és a fix tekercseket kapcsolgatta...
A BD 138 nem túlzás egy 12V ~ 0,2A ventillátorhoz?:)

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 894
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2012. október 1. hétfő, 14:57

No meg egy belül elektronikus venti hogy veszi a levegőt a PWM táptól...
Szétszabdaltam 4-vezetékes, PWM szabályozású ventiket, PIC volt benne. Gondolom nem szeretné, ha a tápját rángatya...
JAni

Avatar
tetye
Chipgyilok
Hozzászólások: 279
Csatlakozott: 2007. augusztus 29. szerda, 6:00
Tartózkodási hely: Perbál
Kapcsolat:

HozzászólásSzerző: tetye » 2012. október 1. hétfő, 16:03

Amit én néztem az csak 3 vezetékes, 8x8cm elég nagy fordulatú, ezért gondoltam a bd138 ra mert nagyon nem tudom hűteni így talán nem is melegedne. A diódát csak azért raktam oda hogy védje a tranyót a ventitől. De igen oda szerintem teszek egy soros diódát is a + ágba hogy csak arra folyjon a feszültség. Rajzon változtattam, de ha gnd re is 10kval húzom és az avr is 10k val húzza 5 v-ra lesz ott elég áram neki a nyitáshoz? Ill ezt a pwm sebességével tudja majd produkálni? Ezekhez a számolásokhoz nem vagyok elég képzett....(Villanyszerelőim van).

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 894
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2012. október 1. hétfő, 18:05

Az NPN-nek biztosan elég a nyitáshoz, a felső PNP tranyó bétáját kellene tudni as pontosításhoz, de ha van szkópod, akkor megnézed, hogy kerekedik-e a kapcsoláskor a PNP-n a fesz. Akkor csökkenteni kell a 4.7k és a 10k-t is (nagyobb bázisáram kell). De ránézésre jónak kell lennie, ha nagyon melegszik a PNP, akkor beállt analógba, akkor mondjuk megfelezed az ellenállásokat.
JAni

Avatar
Robert
Elektronbűvölő
Hozzászólások: 9989
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. október 1. hétfő, 18:05

Az elmélet: megy.
A gyakorlat: próbáld ki - ugyanis max a szimulátorban tudod tesztelni...

Avatar
tetye
Chipgyilok
Hozzászólások: 279
Csatlakozott: 2007. augusztus 29. szerda, 6:00
Tartózkodási hely: Perbál
Kapcsolat:

HozzászólásSzerző: tetye » 2012. október 2. kedd, 9:20

Újra itt! :)
Siker, működik a pwm már tekeri a ventit a fenti kapcsolással bár a bc547 helyett 337-et tettem. Nem melegszik semmi.

Szintet lépnék fordulatszám mérésre.
A kapcsolás a rajzon van ahogy bekötöttem a jeladót.
Programban kérnék segítséget.
Ha INT0-ban kezelem le mint megszakítást és számolom hogy 2 megszakítás közt mennyi idő telik el, megkapom ,hogy mennyit forog, eddig tiszta. De ha én INT0 ban számolgatom akkor mikor fog futni a program többi része? pl a hő mérés, pwm szabályzás, RS485 kommunikáció?
Arra gondoltam, berakom INT0 ba a mérést, RS bytematch-al generál egy megszakítást ha bejön kérés, ekkor kikapcsolná az INT0 amíg lefut, majd vissza. Ez így nem lenne rossz, de a pwm-et nem tudja még ettől szabályozni közben hőmérséklet függvényében. Tudnátok még ebben segíteni hogy hogy oldjam meg?

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 894
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2012. október 2. kedd, 11:54

ITben csak tedd el az időmérő értékét, a többit majd intézi a főprogram:
Int:
idovaltozo=timer
timer=0
return
A főprogramba meg csak az időváltozóval foglalkozol és szabályozod, ami kell. Elvileg az INT-ed "láthatatlan" lesz, többet nem is kell vele foglalkozni. Ha nagyon pipeckedni kell, akkor duplán pufferelheted a változód, de itt szerintem nem okoz nagy hibát.
JAni


Vissza: “Bascom-AVR nyelvű programozás (AVR programozásának lehetőségei)”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 0 vendég