MikroBasic en Servomotor

Arco

Special Member

Dit zal ook wel werken:

pic basic code:


If Strcmp(Str, "Rood") = 0 Then...
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Klopt, was ik al achter.

Alleen (tja, eenmaal bezig.. ;) ) heb ik iets raars met de string die ik lees in de UART:

pic basic code:

if UART1_Data_Ready() = 1 then
   UART1_Read_Text(Str,  "#", 10)
   'Delay_ms(10)
   UART1_Write_Text(Str)
   Str = ""
  End if

.

Als ik de string "1234#" stuur, blijkt er "121234" te worden gelezen (te zien aan wat je terug stuurt).
M.a.w de erste 2 karakters van de string (meest linkse) worden herhaald.

Ik zie niet zo gauw (of eigenlijk helemaal) niet waar dat vandaan komt.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Staat echo niet aan op de PC?
(ik gebruik uart nooit met pollen, veel te lastig. Ik gebruik altijd interrupt...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik verstuur het vanaf een smartphone via Bluetooth.
Met een App: Serial Bluetooth. Die heb ik ook gebruikt voor een lichtkrant.

Die lichtkrant heb ik inderdaad gedaan met interrupt.

Maar ik wilde deze ook eens proberen. Ik volgde de help funktie van MikroBasic:

pic basic code:

Read text until the sequence “OK” is received, and send back what’s been received:

UART1_Init(4800)                           ' initialize UART module
Delay_ms(100)

 while TRUE
   if (UART1_Data_Ready() = 1)             ' if data is received   
     UART1_Read_Text(output, 'OK', 10)  ' reads text until 'OK' is found
     UART1_Write_Text(output)              ' sends back text 
   end if
 wend.

Ipv 'OK' heb ik het karakter '#' gebruikt. Maar dat maakt niks uit.
Nu kan ik natuurlijk de eerste 2 karakters van de ingelezen string er af slopen, maar dat vind ik een lapmiddel.
Het zou gewoon moeten werken. Ik las wel ergens verderop in de help iets over 'Set_Active' wanneer je 2 UARTS hebt in je muc. Maar volgens mij hoeft dat niet.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Het probleem zit hem in de PIC / MB.
Als ik de bluetooth aan de Hterm op de koppel, gaat het prima. Alles wat ik stuur komt keurig terug (RX en TX aan elkaar).

Koppel ik Hterm aan de schakeling met PIC12F1572 en MB:

Dan zie je ook op de PC de 1e 2 karakters herhaald.
In: "1234OK" wordt dan uit: "121234".

Een tweede verschijnsel is dat het ontvangen (of schrijven) van de string pas bij iedere 2e keer gebeurt. Eén beurt slaat hij over.
Of het met elkaar te maken heeft, weet ik niet.

De code is eigenlijk heel simpel, ik weet niet wat ik hier fout aan kan doen.

pic basic code:

if UART1_Data_Ready() = 1 then
   UART1_Read_Text(Str,  "OK", 10)
   Delay_ms(50)
   UART1_Write_Text(Str)
   Str = ""
  End if

Update:
Inmiddels weet ik dat het zenden wel goed gaat. Het zit hem blijkbaar in het inlezen van de string (Str).

Deze krijgt bij binnenkomende waarde "1234OK" de waarde "121234".

[Bericht gewijzigd door Bavelt op dinsdag 18 augustus 2020 17:18:07 (11%)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik heb de string al uitgebreid naar 20 characters. Maakt niks uit.

Nadat hij de eerste 2 bytes van de string heeft ingelezen, start hij blijkbaar opnieuw.

Ik heb nog geprobeerd het verzenden van de string buiten de if UART1_Data_Ready te plaatsen. M.a.w. als de String helemaal is ingelezen.

pic basic code:

if UART1_Data_Ready() = 1 then
   UART1_Read_Text(Str,  "OK", 10)
   Delay_ms(50)
  End if

   Ltrim(Str)
   Rtrim(Str)
   UART1_Write_Text(Str)

Helpt ook niet.

[Bericht gewijzigd door Bavelt op dinsdag 18 augustus 2020 17:33:14 (52%)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik vraag me ook af hoe MB dit doet: je bent de string aan het lezen tot de Delimiter komt. Dat is in dit geval "OK".

Maar deze moet hij er dus wel afhalen, anders zou deze ook in de string komen.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Als ik slechts 1 karakter stuur: "aOK"

Dan komt er terug "a0a". Maar ook pas na 2 keer te hebben verzonden.
Misschien dat de "gemiste" zend alsnog tekens verzamelt..

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Even, heel even had ik het goed toen ik de PC opnieuw opstartte en spanning overal er af.

Maar nu weer heel reproduceerbaar. Eerste twee kakrakters worden herhaald.

Ik las na wat speurwerk dat het verschijnsel vaker voorkomt (maar dan in C-programma's).

Wellicht dat het UART verhaal toch een instabiel communicatie proces is?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik blijf pollen met een UART een 'vieze' bezigheid vinden... ;)
Een delay_ms(50) in die loop gaat zeker niet werken: op 9600 baud mis je dan steeds 480 bits data. (1000/50)
(die stond er ook niet in het voorbeeld...)

Beste is ook om maar 1 character te gebruiken als stop, wel zo handig.
(ik gebruik voor stop meestal <CR>, <ETX>, of "#", voor start <STX> of "*" )

Je moet ook Str op "" zetten voor begin ontvangst, niet erna (dan heeft 't geen zin meer)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ih had idd wat aanpassingen gedaan om wat te experimenteren (zoals de Delay)
Het '#' als stopteken heb ik er later ook in gestopt (dat 'OK' kwam van de help functie van MikroBasic).

Ik blijf pollen met een UART een 'vieze' bezigheid vinden... ;)

Grappig dat je dat zegt. Ik kwam zelf al bijna tot deze conclusie. Ik ervaar dat het niet stabiel overkomt: soms gaat het goed, dan mis ik weer een 'send'.
Dan zie je soms vreemde karakters binnenkomen, dan gaat het weer goed..
etc.

Ik werk met 38400 als baudrate.

Blijkbaar kan je ook de PC op tilt zetten: ik moest hem rebooten nadat Hterm nergens meer op reageerde en alles vast zat. Ook de uc af ten toe resetten (= spanning er af en minuutje wachten) gaf even verlichting.

Kan natuurlijk allemaal ook aan mij liggen. :>

Maar vrijwel alle voorbeelden om een (servo) motortje aan te sturen gaan via bluetooth en in het kielzog daaraan het UART gebeuren.
(Mijn arico heeft veel servo motortjes en wordt aangestuurd vanuit infrarood. Maar is dat niet 'ouderwets'?)

Misschien voor UART toch maar weer overstappen op de interrupt en de Uart1_Read_text() vergeten.

Zo te zien in de datasheet is de interrupt look-alike met andere PIC's die ik gebruik, zoals de PIC16F1847.

Fouten zijn het bewijs dat je het probeert..

Op 19 augustus 2020 10:49:45 schreef Bavelt:
Ik werk met 38400 als baudrate.

Waarom moet dat zo snel? ik vind 9600 als heel snel en veel robuuster bij gebruik van een draadloos systeem en het pollen van data, zelfs in "interrupt mode" hoeft dat niet zo snel te gaan.

LDmicro user.
Bavelt

Golden Member

Waarom moet dat zo snel? ik vind 9600 als heel snel en veel robuuster bij gebruik van een draadloos systeem en het pollen van data, zelfs in "interrupt mode" hoeft dat niet zo snel te gaan.

Ik koos voor 38400 omdat de bluetooth moduultjes zoals de HC05/HC06 dit als een soort 'default' hanteren. De AT-modus werkt daar ook mee.

Maar ik heb het ook wel even teruggebracht naar 9600 zolang ik met een terminal programma als Hterm werk ipv Bluetooth om even te testen.

Dat maakt voor het resultaat niet uit.

Alleen in de oneven zend-commando's krijg ik respons, waarbij de 1e 2 karakters worden herhaald.

Nu kan ik dat natuurlijk in mijn programma opnemen, maar dat is toch mijn eer te na. Dan programmer je op wat er gebeurt en niet op wat er moet gebeuren.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Met 38400 baud is het nog erger: bij een 50mS delay raken er 1920 bits 'zoek' in elke loop...

Je kunt bij een simpele UART (zonder FIFO) niet zomaar delays invoegen en denken "data haal ik later wel eens op"
(als er een nieuw karakter binnenkomt moet de buffer geleegd zijn...)
Al die 'blocking' functies als read_text kun je beter vergeten, altijd ellende...

Ik vind zoiets veel frisser: (voorbeeld met "#" als stopteken):
Moet alleen nog een tellertje in voor max. pogingen, anders hangt de boel als "#" nooit wordt ontvangen.

pic basic code:


Str    = ""
RxChar = ""
While RxChar <> "#"
  If UART1_Data_Ready then 
    UART1_Read(RxChar) 
    If RXChar <> "#" Then Str = Str + RxChar End If
  End If
Wend

[Bericht gewijzigd door Arco op woensdag 19 augustus 2020 12:03:02 (11%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Wat ik van een taaltje als "PICBASIC" of "arduino" verwacht is dat als ze dingen als read-a-string-from-uart aanbieden ze dan ook het moeilijkere (voor beginners) deel op zich nemen: interrupts, circulair buffertje. Dat de hardware maar 1 byte buffer in de uart heeft, dat boeit dan niet meer.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Op 19 augustus 2020 11:08:37 schreef Bavelt:
[...]
Ik koos voor 38400 omdat de bluetooth moduultjes zoals de HC05/HC06 dit als een soort 'default' hanteren. De AT-modus werkt daar ook mee.

De HC05/06 zijn standaard ingesteld op 9600b als ik het goed onthouden heb en de "AT-modus" is een protocol en heeft niks te maken met de baudrate.

LDmicro user.
Arco

Special Member

Vooral picbasic heeft veel 'blocking' functies, en da's niet altijd even handig...
@rew: In de default libraries van Mikrobasic wordt niet van interrupts gebruik gemaakt juist om het simpel te houden voor beginners.

Daarbij zijn libraries reeds gecompileerde brokken code.
Als er meerdere dezelfde interrupt nodig zouden hebben wordt het al gauw gecompliceerd en lastig...

Interrupt is simpel en geen omkijken naar... ;)
RxOK is een flag die geset wordt na ontvangst. RxRead is een flag die in main() geset wordt na verwerken van de data. (wordt in irq weer gereset)

pic basic code:


Interrupt:

  If RCIF_Bit Then
    If RxRead Then 
      RxRead = 0 
      RxOK   = 0
      Str    = ""
    End If
    RxChar = RCREG
    If (RxChar <> "#") And (RxOK = 0) Then 
      Str = Str + RxChar
    Else
      RxOK = 1
    End If
    RCIF_Bit = 0
  End If
End Interrupt:
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

De eerste code van Arco is inderdaad hoopgevend :)
(met een kleine aanpassing):

De juiste syntax voor het lezen van een karakter in MB is

pic basic code:

 RxChar = UART1_Read()

Wordt dus nu:

pic basic code:

Str    = ""
  RxChar = ""
  While RxChar <> "#"
    If UART1_Data_Ready then
      RxChar = UART1_Read()
      If RXChar <> "#" Then Str = Str + RxChar End If
    End If
  Wend

Ik heb het met verschillende snelheden geprobeerd en tot nu toe nog geen gekke tekens / karakters binnengekregen...

M.a.w. Het lijkt te werken... :D

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

RxChar = UART1_Read is hetzelfde als RxChar = RCREG (laatste is alleen simpeler en waarschijnlijk minder overhead...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

jawel, maar jij had in de code

pic basic code:

UART1_Read(RxChar) 

gezet. Dat mag niet volgens de syntax... :)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Nu eens kijken of ik die Baudrate van de bluetooth HC06 weer op 9600 kan zetten. (staat nu op 38400).

De meeste voorbeelden die ik vind werken mnet de Arduino..
Maar kan ik met Hterm dan geen AT-commando's versturen naar dat ding?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 20 augustus 2020 10:28:56 schreef Arco:
https://www.instructables.com/id/AT-command-mode-of-HC-05-Bluetooth-mo…

Deze had ik idd gezien. Lijkt makkelijk: TX aan de Rx van de BT (via level shifter) en Rx aan TX.

Bluetooth connection uit en het ding (HC06) zou in AT-mode moeten staan.

En dan via Hterm de AT-commando's invoeren.

Enkele commando's (zoals AT+BAUD4) lijkt hij te herkennen, maar het resultaat is steevast error1003.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dit ook gelezen?:

Now there is a small drawback for HC06, it does not wait for any termination character for each AT command entry.
Instead, it acts to whatever character you entered after one second.
Hence, if you are not able to complete a command entry within a second, it will be ignored.

Kan ook zijn dat er geen <CR> en/of <LF> achter mogen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com