Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Visual Basic 6 - VB6 scrivere un bytes da un arry senza usare cicli FOR - HELP per la sintassi
Forum - Visual Basic 6 - VB6 scrivere un bytes da un arry senza usare cicli FOR - HELP per la sintassi

Avatar
iz1kbp (Normal User)
Rookie


Messaggi: 26
Iscritto: 29/02/2020

Segnala al moderatore
Postato alle 18:54
Martedì, 02/05/2023
Buongiorno a tutti,
Sono alla ricerca di un suggerimento su come velocizzare una mia routine, che ora comunque funziona.
Per informazione, creo un byte secondo il protocollo ArtNet per il pilotaggio di fari intelligenti (luci per spettacoli)
Codice sorgente - presumibilmente VB.NET

  1. Private Sub Timer7_Timer()
  2.  
  3. 'stringa artnet>>>>>>>>>>>>>>
  4. artnet0 = "Art-Net"
  5. For n = 1 To 7
  6.     singolo = Mid(artnet0, n, 1)
  7.         buffer(n - 1) = Asc(singolo) ' creo la frase Art-net
  8. Next
  9. 'fine stringa artnet >>>>>>>>>>
  10. buffer(7) = Val(vbNullChar)                 ' richiesto carattere null
  11. 'fine creazione stringa>>>>>>
  12. buffer(8) = "0"                      'tipo di dato >  5000 (80) per dmx
  13. buffer(9) = "80"                     '  lo
  14. buffer(10) = "0"                     'protocollo hi >1400
  15. buffer(11) = "14"                    '  lo
  16. If sequenza > 255 Then sequenza = 0
  17. buffer(12) = sequenza '"0"          'sequenza> numero di trasmissione 0 per disabilitare, 1toff
  18. buffer(13) = "0"                     'physical porta dmx in ingresso ?
  19. 'universo dmx >>>>>>>>>>>>>>>>
  20. buffer(14) = "0" 'subuni             'universo
  21. buffer(15) = "0"                     'net
  22. 'lunghezza array dmx>>>>>>>>>>
  23. buffer(16) = "2"                    'lunghezza array dmx > hi > 1 per un singolo canale
  24. buffer(17) = "0"                    'lunghezza lo >0
  25. 'fine costruzione stringa ora carico i valori dei 512 canali >>>>>>>>>>>>>>>>>>>>>>>>>>  (XXX)
  26. Dim artnetch As Integer
  27. For artnetch1 = 1 To 512
  28.     buffer(17 + artnetch) = generalech(artnetch)  >>> questa è la matrice in cui salvo i valori dei singoli canali GENERALCH(CANALE)=VALORE
  29. Next
  30. 'fine costruzione pacchetto canali >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  (YYY)
  31. 'Spedisco la stringa via UDP
  32. stringa = StrConv(buffer, vbUnicode)
  33. On Error GoTo errore_udp
  34. If sockattivo(0) = True And host0(0) = 1 Then sockMain.SendData stringa


Questo il funzionamento per sommi capi:
Il programma memorizza un una matrice di 512 caselle, il valore dei singoli canali dmx (valore della luce) che vanno appunto da 1 a 512, per 255 livelli ciascuno.
Nel momento in cui modifico il valore di un canale, es il 10 lo porto al max, vado a modificare solo la casella,, ad esempio, generalech(10) =255.
Il protocollo prevere che questa matrice sia mandata in continuo da 1 a 512 sulla rete.
Di queste matrici, il protocollo ArtNet, ne prevede...16530.
Come si vede, io creo il byte da spedire , scansionando tutta la matrice dei calori dei canali DMX da 1 a 512 (il codice compreso tra XXX e YYY)
Usando solo una matrice, il ciclo for riesce a star dentro nel normale refresh dell'invio dei dati ( lo faccio ogni 10 ms)..se però utilizzo 3 matrici, il ciclo FOR mi fa perdere molti dati, perchè se io cambio il valore di un canale nella matrice 1, ma nel frattempo sta processando la matrice 2 e poi deve fare la matrice 3, perdo 3 informazioni.

La domanda è :esiste un metodo per evitare il ciclo for, per creare questi bytes tutto in un colpo?
Ho letto in forum inglesi di una API "RtlMoveMemory API function to copy data" che muove appunto blocci di memoria.Purtroppo le mie conoscenze sono un po limitate.qualcuno potrebbe illuminarmi/suggerirmi la corretta sintassi
dovre essere una cosa del genere ma non riesco a capire la sintassi giusta
Codice sorgente - presumibilmente Visual Basic 6

  1. CopyBytes buffer(da 17 a 512), ByVal generalech (da 1 a 512), 512



grazie a chiunque mi possa dare una mano.:)

Mario

PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 20:36
Martedì, 02/05/2023
Se ho capito bene all'inizio del codice scrivi

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

e al posto della For dovrebbe bastare questa linea

CopyMemory buffer(18), generalech(1), 512



Detto questo, non capisco perché devi copiare i dati se li hai già.
Se assumiamo che buffer sia costituito SOLO dai byte da 0 a 17 allora puoi evitare la copia e scrivere direttamente

stringa = StrConv(buffer, vbUnicode) & StrConv(generalech, vbUnicode)

Ultima modifica effettuata da il 02/05/2023 alle 20:49
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1364
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 21:21
Martedì, 02/05/2023
Aspetto la risposta che darai a nessuno.

La porzione di codice:
Codice sorgente - presumibilmente VB.NET

  1. Dim artnetch As Integer
  2. For artnetch1 = 1 To 512
  3.     buffer(17 + artnetch) = generalech(artnetch)  '>>> questa è la matrice in cui salvo i valori dei singoli canali GENERALCH(CANALE)=VALORE
  4. Next


nel For usi: artnetch1 ma poi per ottenre l'indice usi: artnetch, è un errore nella trascrizione oppure...
Se il codice è così e funziona, come ti ha già detto nessuno fai un ciclo che fa 512 volte la stessa cosa.

Ultima modifica effettuata da Carlo il 02/05/2023 alle 21:24


in programmazione tutto è permesso
PM Quote
Avatar
iz1kbp (Normal User)
Rookie


Messaggi: 26
Iscritto: 29/02/2020

Segnala al moderatore
Postato alle 8:01
Mercoledì, 03/05/2023
@Carlo...si, è solo un errore di riporto.
@Nessuno...il programma è nato circa 10 anni fa (gia evoluzioni di precedenti versioni quando usavo ancora Io/Out su porte LPT ) quando questo protocollo non lo conoscevo e tutte le implementazioni successivo sono state fatte partendo dal modello iniziale.
Ho ragionato su quello che hai scritto, me devo dire che hai ragione: io gia creo una matrice (pezzo per pezzo) e poi , ignorantemente, vado a ricrearne un'altra "identica" spazzolando quella appena creata ...perdendo tempo!!
Posso creare direttamente il singolo byte all'inizio, mentre creo il singolo pezzo di matrice in questo modo mi trovo il pacchetto gia fatto e devo solo spedire la stringa convertita.
Evito cosi di fare giri strani con le API..

Grazie per lo spunto!!:k:

Mario

PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 19:56
Mercoledì, 03/05/2023
Ok facci sapere

P.S. Per curiosità, cosa usavi per l'output su I/O verso LPT1?

PM Quote
Avatar
iz1kbp (Normal User)
Rookie


Messaggi: 26
Iscritto: 29/02/2020

Segnala al moderatore
Postato alle 10:22
Giovedì, 04/05/2023
Testo quotato

Postato originariamente da nessuno:

Ok facci sapere

P.S. Per curiosità, cosa usavi per l'output su I/O verso LPT1?



Ciao ragazzi...dunque risolto.
Mi sono ricordato che gia avevo predisposto la creazione della singola casella della matrice e quindi, dopo avere controllato tutte le routine interessate, è stato "sufficiente" affiancare la creazione del singolo byte...."semplicemente"

per quanto riguarda l'I/O...usavo inpout32.dll per il comandare una porta LPT che a sua volta comandava un PIC per la creazione del segnale dmx (rs485)..ma ero legato al massimo ad avere 128 canali per via del fatto che usavo solo 8 bit

Grazie ancora per gli spunti!:k:

Mario

PM Quote