Hallo,
Ik heb onderstaande H-bridge opgebouw om een motor links- en rechtsom te laten draaien. Deze werkt perfect met dank aan HvZ voor het duidelijke schema. Ik vraag mij alleen af waarom weerstand R4 van 0,1 ohm erin zit. Kan iemand dat uitleggen?
http://www.uploadarchief.net/files/download/eind%20-%20trap.jpg
http://www.uploadarchief.net/files/download/eind%20-%20trap.jpg
Heeft iemand al ervaring met dit schema en dus ook met die stroommeting. Kan ik die lijn gebruiken om met een ingang van de pic en pulsin commando zo de stroom te meten?
Alvast bedankt.
Dirk
Hallo Dirk, bedankt.
Die weerstand zit er in om de stroom te meten, als er een stroom loopt krijg je een spanningsval over de weerstand. Die spanning kan je aanbieden op bv een ingang van een controller, en zo de stroom in de gaten houden die door de regelaar loopt. En je kan het ook eventueel gebruiken als terugkoppeling, dus als je motor zwaarder moet trekken wordt de regelaar bijgeregeld. Dit gebeurd beide software matig. Maar je kan het ook gewoon los laten, en niet aansluiten. Net wat je zelf wil. 
EDIT:
Het signaal komt op een analoge ingang, niet de functie pulsin gebruiken. Pulsin is meer voor frequentie's.
[Bericht gewijzigd door Lambiek op (10%)]
Lambiek bedankt voor de uitleg. Ik werd op het verkeerde been gezet door het pulssignaal teken wat erbij staat. Heb inmiddels de stroommeting getest en werkt perfect. Nogmaals dank voor de uitleg en het schema.
Ik ben een radiografische tank aan het maken. De motoren verbruiken 4A vandaar dat ik opzoek was naar een H-bridge en vond die van jou mooi ook ivm die stroommeting. Die stroommeting wil ik gebruiken om het toerental gelijk te houden dan wel bij een blokkade dat een uit gang uitschakelt en dmv een led aangeeft waar het probleem zit.
Ben nu alleen nog opzoek naar een methode om als een motor langer dan bijv 1 minuut draait deze uitschakelt. Ben al aan het zoeken of het met een teller en een interrupt kan maar heb nog niets gevonden. Zal een nieuwe discussie openen als ik niets blijf vinden.
Waarom wil je de motor uitschakelen als hij langer dan een minuut draaid. Of is dat inverband met de beveiliging.
Er gaan meerdere mensen rijden met het geheel. Dus om iedereen dezelfde tijd te laten rijden leek mij dat een leuke optie. Ik zeg nu een minuut maar kan langer worden.
Ik heb gezocht op WatchDogTimer of daar iets mee te doen is maar snap nog niet zoveel van interrupts te programmeren. Ik werk met Proton. Dus je zou zeggen moet niet zo moeilijk zijn.
Je kan het het beste met on interrupt doen, dat draaid op de achtergrond van je programma mee en heeft geen invloed op de rest van je programma.
Hier heb je een voorbeeld met on interrupt.
Device 16F887 ; Processor type
ASM ; Config settings
CONFIG_REQ
__CONFIG _CONFIG1, INTRC_OSC_NOCLKOUT & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON
__CONFIG _CONFIG2, WRT_OFF & BOR21V
ENDASM
;Device 16F877 ; processor type
;XTAL 10 ; crystal 10 Mhz
ON_INTERRUPT timer
;Config HS_OSC,_ ; cristal groter dan 4MHz
;WDT_OFF,_ ; Watchdog Timer Enable uit
;PWRTE_ON,_ ; Power-up Timer Enable aan
;BODEN_OFF,_ ; Brown-out Reset Enable uit
;LVP_OFF,_ ; Low Voltage Programming uit
;CPD_OFF,_ ; Memory Code Protection uit
;WRTE_ON,_ ; Write Enable aan
;DEBUG_ON,_ ; In-Cir Debugger Mode aan
;CP_OFF ; Code Protection uit
ALL_DIGITAL true ; Alle poorten digitaal
Symbol aan = 1 ; 1 is hoog
Symbol uit = 0 ; 0 is laag
Symbol GIE = INTCON.7 ; Enable interrupt
Symbol T0IF = INTCON.2 ; TIMER0 interrupt vlag
Symbol T0IE = INTCON.5 ; TIMER0 interrupt enabel
Symbol PS0 = OPTION_REG.0 ; Instelling prescaler
Symbol PS1 = OPTION_REG.1 ; Instelling prescaler
Symbol PS2 = OPTION_REG.2 ; Instelling prescaler
Symbol PSA = OPTION_REG.3 ; Instelling oscillator
Symbol T0SE = OPTION_REG.4 ; Instelling puls H/L - L/H
Symbol T0CS = OPTION_REG.5 ; Instelling clock intern of extern
Symbol I_0 = PORTA.0 ; Ingang_0
Symbol I_1 = PORTA.1 ; Ingang_1
Symbol I_2 = PORTA.2 ; Ingang_2
Symbol I_3 = PORTA.3 ; Ingang_3
Symbol I_4 = PORTA.5 ; Ingang_4
Symbol I_5 = PORTE.0 ; Ingang_5
Symbol I_6 = PORTE.1 ; Ingang_6
Symbol I_7 = PORTE.2 ; Ingang_7
Symbol Q_0 = PORTB.0 ; Uitgang_0
Symbol Q_1 = PORTB.1 ; Uitgang_1
Symbol Q_2 = PORTB.2 ; Uitgang_2
Symbol Q_3 = PORTB.3 ; Uitgang_3
Symbol Q_4 = PORTB.4 ; Uitgang_4
Symbol Q_5 = PORTB.5 ; Uitgang_5
Symbol Q_6 = PORTD.2 ; Uitgang_6
Symbol Q_7 = PORTD.3 ; Uitgang_7
Symbol Q_8 = PORTD.4 ; Uitgang_8
Symbol Q_9 = PORTD.5 ; Uitgang_9
Symbol Q_10 = PORTD.6 ; Uitgang_10
Symbol Q_11 = PORTD.7 ; Uitgang_11
Symbol Q_12 = PORTC.3 ; Uitgang_12
Symbol Q_13 = PORTD.0 ; Uitgang_13
Symbol Q_14 = PORTD.1 ; Uitgang_14
Symbol Q_15 = PORTC.7 ; Uitgang_15
Symbol Q_16 = PORTC.6 ; Uitgang_16
Symbol Q_17 = PORTC.5 ; Uitgang_17
Dim puls As Bit ; Var_puls_1/10 sec
Dim B_0 As Bit ; Var_bit_0
Dim B_1 As Bit ; Var_bit_1
Dim B_2 As Bit ; Var_bit_2
Dim B_3 As Bit ; Var_bit_3
Dim B_4 As Bit ; Var_bit_4
Dim B_5 As Bit ; Var_bit_5
Dim B_6 As Bit ; Var_bit_6
Dim B_7 As Bit ; Var_bit_7
Dim B_8 As Bit ; Var_bit_8
Dim B_9 As Bit ; Var_bit_9
Dim B_10 As Bit ; Var_bit_10
Dim B_11 As Bit ; Var_bit_11
Dim B_12 As Bit ; Var_bit_12
Dim B_13 As Bit ; Var_bit_13
Dim B_14 As Bit ; Var_bit_14
Dim B_15 As Bit ; Var_bit_15
Dim B_16 As Bit ; Var_bit_16
Dim B_17 As Bit ; Var_bit_17
Dim B_18 As Bit ; Var_bit_18
Dim B_19 As Bit ; Var_bit_19
Dim TMR_1 As Word ; Timer1
Dim TMR_2 As Word ; Timer2
Dim TMR_3 As Word ; Timer3
Dim TMR_4 As Word ; Timer4
Dim TMR_5 As Word ; Timer5
Dim TMR_6 As Word ; Timer6
Dim TMR_7 As Word ; Timer7
Dim TMR_8 As Word ; Timer8
Dim TMR_9 As Word ; Timer9
Dim TMR_10 As Word ; Timer10
Dim TMR_11 As Word ; Timer11
Dim TMR_12 As Word ; Timer12
Dim TMR_13 As Word ; Timer13
Dim TMR_14 As Word ; Timer14
Dim TMR_15 As Word ; Timer15
Dim TMR_16 As Word ; Timer16
Dim TMR_17 As Word ; Timer17
Dim TMR_18 As Word ; Timer18
Dim TMR_19 As Word ; Timer19
Dim TMR_20 As Word ; Timer20
Dim DW_TEMP As Word
Dim VAL_TIMER As Word ; Variabele waarde timer
Dim LIMITE_TIMER As Word ; Variabele limite
GIE = 0 ; Zet interrupt uit
GoTo instelling ; Ga naar instelling
; -------------------------------------------------------------------
; INTERRUPT ROUTINE ; Plaats eerst de interrupt routine
; -------------------------------------------------------------------
timer:
Inc VAL_TIMER ; Increment waarde timer
T0IF = 0 ; Wis interrupt flag
Context Restore
instelling: ; Instelling register
PS0 = 0 ; Prescaler bit_0
PS1 = 0 ; Prescaler bit_1
PS2 = 1 ; Prescaler bit_2
PSA = 0 ; Prescaler toegewezen aan TIMER0
T0SE = 0 ; Trigger van laag naar hoog
T0CS = 0 ; Trigger door interne clock
LIMITE_TIMER = 3 ; INT(2500000 /(256*32))
VAL_TIMER = 0 ; Variabele waarde timer is 0
TMR0 = 0 ; Reset TIMER0
T0IE = 1 ; TIMER0 Interrupt enabel aan
GIE = 1 ; Zet Interrupt aan
;543210 ; Hulpregel poort_A
PORTA = %000000 ; Maak poort_A laag
TRISA = %111111 ; Poort_A I/O
;543210 ; Hulpregel poort_B
PORTB = %000000 ; Maak poort_b laag
TRISB = %000000 ; Poort_B I/O
;76543210 ; Hulpregel poort_C
PORTC = %00000000 ; Maak poort_C laag
TRISC = %00000000 ; Poort_C I/O
;76543210 ; Hulpregel poort_D
PORTD = %00000000 ; Maak poort_D laag
TRISD = %00000000 ; Poort_D I/O
;210 ; Hulpregel poort_E
PORTE = %000 ; Maak poort_c laag
TRISE = %111 ; Poort_E I/O
;---------------------------------------
; Zet - Uigangen, Timers, En Bits Laag
;---------------------------------------
Q_0 = 0
Q_1 = 0
Q_2 = 0
Q_3 = 0
Q_4 = 0
Q_5 = 0
Q_6 = 0
Q_7 = 0
Q_8 = 0
Q_9 = 0
Q_10 = 0
Q_11 = 0
Q_12 = 0
Q_13 = 0
Q_14 = 0
Q_15 = 0
Q_16 = 0
Q_17 = 0
B_0 = 0
B_1 = 0
B_2 = 0
B_3 = 0
B_4 = 0
B_5 = 0
B_6 = 0
TMR_1 = 0
TMR_2 = 0
TMR_3 = 0
TMR_4 = 0
TMR_5 = 0
;------------------
; Hoofd programma
;------------------
MAIN:
While 1 = 1
Include "Programma.bas"
Wend
End
Dit is maar een klein stukje van het programma, maar dan kan je zien hoe het met on interrupt zit. Ik hoop dat het een beetje te begrijpen is zo. Weet alleen niet of je ook met pic controllers werkt, zoniet dan kan je dit vergeten.
; -------------------------------------------------------------------
; INTERRUPT ROUTINE ; Plaats eerst de interrupt routine
; -------------------------------------------------------------------
timer:
Inc VAL_TIMER ; Increment waarde timer
T0IF = 0 ; Wis interrupt flag
Context Restore
Lambiek, Ik gebruik toevallig ook PIC van microchip. Ik denk het een beetje te begrijpen. Heb de help-file er naast gelegd. De instellingen zijn nog niet geheel duidelijk maar dat komt wel. Zal er morgen eens mee stoeien.
Zodra bovenstaande code de gewenste tijd/waarde (VAL_TIMER) heeft bereikt mag een poort laag worden. Moet ik dat in het hoofdprogramma regelen of ook in de interrupt-routine?
Wederom bedankt.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Het probleem met interrupts is dat het het hoofdprogramma onderbreekt. Als dat te lang duurt kunnen er dingen misgaan, maar dat hangt van jou hoofdprogramma af.
Omdat het heel "gemene" fouten oplevert die lastig te vinden zijn, hebben veel mensen zich aangeleerd om de interrupts zo snel mogelijk te maken. Dus als je zo in de interrupt alleen maar een tellertje ophoogt dan kan dat vrijwel altijd. Dan merk je vanzelf als er te veel werk is, en dat hij het niet aankan. Als je interrupt te lang wordt, dan gaat het subtiel fout.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Dat kan inderdaad een probleem zijn, maar ik ben er geen voorstander van om de interrupt vlaggen te laten zetten. De interrupt flag kan dan al voldoen, dus dan is de hele ISR overbodig. Het is natuurlijk wel verstandig om de ISRs zo kort mogelijk te houden. In je main loop hoort sowieso niets tijdkritisch te staan.
Het beste kan je een puls genereren met je interrupt, en deze puls dan in je hoofd programma gebruiken. Zo heb ik het ook gedaan, en bij mij werkt dat goed.
EDIT:
Dit is misschien iets duidelijker.
Device 16F887 ; Processor type
XTAL 10 ; crystal 10 Mhz
ON_INTERRUPT timer
ASM ; Config settings
CONFIG_REQ
__CONFIG _CONFIG1, INTRC_OSC_NOCLKOUT & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON
__CONFIG _CONFIG2, WRT_OFF & BOR21V
ENDASM
ALL_DIGITAL true ; Alle poorten digitaal
Symbol aan = 1 ; 1 is hoog
Symbol uit = 0 ; 0 is laag
Symbol GIE = INTCON.7 ; Enable interrupt
Symbol T0IF = INTCON.2 ; TIMER0 interrupt vlag
Symbol T0IE = INTCON.5 ; TIMER0 interrupt enabel
Symbol PS0 = OPTION_REG.0 ; Instelling prescaler
Symbol PS1 = OPTION_REG.1 ; Instelling prescaler
Symbol PS2 = OPTION_REG.2 ; Instelling prescaler
Symbol PSA = OPTION_REG.3 ; Instelling oscillator
Symbol T0SE = OPTION_REG.4 ; Instelling puls H/L - L/H
Symbol T0CS = OPTION_REG.5 ; Instelling clock intern of extern
Symbol I_0 = PORTA.0 ; Ingang_0
Symbol I_1 = PORTA.1 ; Ingang_1
Symbol I_2 = PORTA.2 ; Ingang_2
Symbol I_3 = PORTA.3 ; Ingang_3
Symbol I_4 = PORTA.5 ; Ingang_4
Symbol I_5 = PORTE.0 ; Ingang_5
Symbol I_6 = PORTE.1 ; Ingang_6
Symbol I_7 = PORTE.2 ; Ingang_7
Symbol Q_0 = PORTB.0 ; Uitgang_0
Symbol Q_1 = PORTB.1 ; Uitgang_1
Symbol Q_2 = PORTB.2 ; Uitgang_2
Symbol Q_3 = PORTB.3 ; Uitgang_3
Symbol Q_4 = PORTB.4 ; Uitgang_4
Symbol Q_5 = PORTB.5 ; Uitgang_5
Dim puls As Bit ; Var_puls_1/10 sec
Dim B_0 As Bit ; Var_bit_0
Dim B_1 As Bit ; Var_bit_1
Dim B_2 As Bit ; Var_bit_2
Dim B_3 As Bit ; Var_bit_3
Dim B_4 As Bit ; Var_bit_4
Dim TMR_1 As Word ; Timer1
Dim TMR_2 As Word ; Timer2
Dim TMR_3 As Word ; Timer3
Dim TMR_4 As Word ; Timer4
Dim TMR_5 As Word ; Timer5
Dim VAL_TIMER As Word ; Variabele waarde timer
Dim LIMITE_TIMER As Word ; Variabele limite
GIE = 0 ; Zet interrupt uit
GoTo instelling ; Ga naar instelling
; --------------------------------------------------------------------------
; INTERRUPT ROUTINE ; Plaats eerst de interrupt routine
; --------------------------------------------------------------------------
timer:
Inc VAL_TIMER ; Increment waarde timer
T0IF = 0 ; Wis interrupt flag
Context Restore
instelling: ; Instelling register
PS0 = 0 ; Prescaler bit_0
PS1 = 0 ; Prescaler bit_1
PS2 = 1 ; Prescaler bit_2
PSA = 0 ; Prescaler toegewezen aan TIMER0
T0SE = 0 ; Trigger van laag naar hoog
T0CS = 0 ; Trigger door interne clock
LIMITE_TIMER = 3 ; INT(2500000 /(256*32)) (puls_10 milisec)
VAL_TIMER = 0 ; Variabele waarde timer is 0
TMR0 = 0 ; Reset TIMER0
T0IE = 1 ; TIMER0 Interrupt enabel aan
GIE = 1 ; Zet Interrupt aan
;543210 ; Hulpregel poort_A
PORTA = %000000 ; Maak poort_A laag
TRISA = %111111 ; Poort_A I/O
;543210 ; Hulpregel poort_B
PORTB = %000000 ; Maak poort_b laag
TRISB = %000000 ; Poort_B I/O
;76543210 ; Hulpregel poort_C
PORTC = %00000000 ; Maak poort_C laag
TRISC = %00000000 ; Poort_C I/O
;76543210 ; Hulpregel poort_D
PORTD = %00000000 ; Maak poort_D laag
TRISD = %00000000 ; Poort_D I/O
;210 ; Hulpregel poort_E
PORTE = %000 ; Maak poort_c laag
TRISE = %111 ; Poort_E I/O
;---------------------------------------
; Zet - Uigangen, Timers, En Bits Laag
;---------------------------------------
Q_0 = 0
Q_1 = 0
Q_2 = 0
Q_3 = 0
Q_4 = 0
Q_5 = 0
B_0 = 0
B_1 = 0
B_2 = 0
B_3 = 0
B_4 = 0
TMR_1 = 0
TMR_2 = 0
TMR_3 = 0
TMR_4 = 0
TMR_5 = 0
;------------------
; Hoofd programma
;------------------
MAIN:
While 1 = 1
If VAL_TIMER > LIMITE_TIMER Then ; Als V_T groter dan 3 dan
VAL_TIMER = 0 ; V_T is 0
puls = 1 ; Puls is 1
EndIf ; Einde als
;----------------------------
If puls = 1 Then
Q_0 = 1
EndIf
If puls = 0 Then
Q_0 = 0
EndIf
;----------------------------
If puls = 1 Then
TMR_1 = TMR_1 + 1
If TMR_1 > 10 Then
Q_1 = 1
If TMR_1 > 20 Then
Q_1 = 0
EndIf
EndIf
EndIf
;---------------------------
If puls = 1 Then
TMR_2 = TMR_2 + 1
If TMR_2 > 20 Then
Q_2 = 1
If TMR_2 > 30 Then
Q_2 = 0
EndIf
EndIf
EndIf
puls = 0
Wend
End
[Bericht gewijzigd door Lambiek op (96%)]
Ik ben mij ervan bewust dat een interrupt behandeling zo kort mogelijk moet.
Heb inmiddels bovenstaande source verwerkt in mijn programma maar heb het nog niet werkend. Heb wel het idee dat ik snap hoe het een en ander werkt. Zal nog eens goed moeten kijken waar het misgaat. In ieder geval iedereen bedankt voor het meedenken.
Het werkt! Had de eind waarde (LIMITE_TIMER)niet aangepast. Even eten dan zie je het meteen.
Ben er zeer blij mee. Zo leer je elke keer weer bij. Mijn dank is groot.
Ga me nu in de stroommeting verdiepen.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
@Lambiek: ik heb wel een paar aanmerkingen op die code, maar ik wil even voorop stellen dat ik dit als opbouwende kritiek bedoel.
Ten eerste heb je een race condition in regel 3-6 van main. Als de ISR, actief wordt tussen de if-statement en het resetten van VAL_TIMER, mis je een puls.
Met Q0=puls kun je 5 regels besparen.
Ik neem aan dat het je bedoeling was om Q1 en Q2 aan te zetten als het aantal pulsen tussen resp. 10-20 en 20-30 ligt, en niet voor een bepaalde tijd. Echter, zodra je boven die hoogste waarde komt, ga je korte pulsjes op je uitgangen zetten (een paar clockcycles), omdat je de uitgang eerst hoog zet en direct weer laag.
Hoi SparkyGSX
Dat commentaar dat geeft niet, twee zien meer dan een.
Helemaal boven in main wordt de puls aangezet, en helemaal onder wordt hij gereset. Dan heb ik toch maar een puls als het programma een keer door main gelopen is.
En dat van Q0, Q2, en TMR_1, en TMR_2 was even een voorbeeld voor DKH. Maar je hebt gelijk, het had ook met Q0 = puls gekunt.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Ik bedoel dat je een puls mist als je die if-statement in gaat, vervolgens de ISR gaat lopen, waarbij VAL_TIMER opgehoogd wordt, en je die vervolgens op nul zet, waarbij je dus een event weg gooit.
Misschien zijn die korte spikes geen probleem, maar als daar een digitaal systeem aan hangt gaat het wel mis.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Je kunt die If statement in een critical section zetten (alle interrupts uit),of voor de If statement de waarde opslaan, en het verschil met de vorige opgeslagen waarde bepalen, om te bekijken of het alweer tijd is om die If statement in te gaan. Op die manier hoef je de waarde binnen de main nooit te veranderen.
Dus:
Temp = int_var
If ((temp - last_value + 256) AND 255) > 10
Last_value = temp
Doe_iets
End if
Die + 256 en AND 255 zijn nodig om overflow problemen te ondervangen.
Dat probleem met de korte spikes kun je oplossen door eerst te testen op de hoogste waarde, en als die nog niet gehaald is, op de laagste waarde.
Dus:
If waarde > 20 doe_iets
Else if waarde > 10 doe_iets_anders
Sjoerd Kreyns
Golden Member
SMD weerstandjes zoeken in grijze vloerbedekking is ook een uitdaging ... 8*1=255 ... Het nadeel van ruimte: Als je het hebt, staat het binnen de kortste keren weer vol.
Hallo Sjoerd,
Deze is goed, het komt niet zo heel precies voor de fet.
http://nl.rs-online.com/web/p/mosfet/5409941/
Weet niet wat je er mee gaat doen, maar als je meer stroom nodig hebt, kan je ook de TIP142 vervangen voor de MJ11016, en de TIP147 vervangen voor de MJ11015. Verder hoef je niets aan te passen.
Let even op de vrijloop diode's dat moeten vastrecovery type's zijn.
En de waarde even kiezen voor de stroom die je gaat regelen.
Gebruik zelf altijd dit type koellichaam, voor de regelaar met de TIP'S.
http://nl.rs-online.com/web/p/heat-sinks/0268111/
Hier kan je dan ook eventueel nog ventilatoren op zetten.
Als je nog vragen hebt hoor ik het wel.
Sjoerd Kreyns
Golden Member
SMD weerstandjes zoeken in grijze vloerbedekking is ook een uitdaging ... 8*1=255 ... Het nadeel van ruimte: Als je het hebt, staat het binnen de kortste keren weer vol.
Dankje!
Die heeft Dickbest niet, maar als het niet precies komt, zal de IRL540NPBF ook wel goed zijn aangezien dat een logic fet is.
Is er een printlayout beschikbaar? Anders ontwerp ik zelf een print.
PS. Sorry voor de topic kaap, maar nu blijven de vragen bij elkaar, aangezien dit ook over het schema gaat.