Go Down

Topic: Campionamento segnale analogico Arduino (Read 642 times) previous topic - next topic

gpb01

#30
May 21, 2019, 12:38 pm Last Edit: May 21, 2019, 12:38 pm by gpb01
... beh, volendo, ci sarebbe la Serial.readBytes() ... ma legge carattere a carattere e ritorna dopo aver letto N caratteri o per timeout ::)

Però non è la stessa cosa ... ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

Standardoil

A parte che la ricezione lo OP la fa su pc, ma per parlare a livello concettuale, una read () multibyte non avrebbe molto senso, dato che delle due l'una
O sappiamo quanti byte abbiamo ricevuto e corrispondono a quelli che ci aspettiamo, e un semplice for ci toglie le castagne dal fuoco
Oppure non ne abbiamo ancora ricevuti abbastanza, e quindi è  inutile fare la read

Prima legge di Nelson (che sono io): fai le stesse cose sempre alla stessa maniera, quegli errori li hai già corretti

Non bado a studenti, che vadano a copiare da un'altra parte

Se io ti domando e tu non mi rispondi vuol dire che non ti serve più

docdoc

Edit: ci sarebbe parseInt() che però restituisce un long.
Non solo, la parseInt() legge caratteri, non byte (rappresentazione binaria)...
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

gpb01

#33
May 21, 2019, 01:37 pm Last Edit: May 21, 2019, 01:37 pm by gpb01
... O sappiamo quanti byte abbiamo ricevuto e corrispondono a quelli che ci aspettiamo, e un semplice for ci toglie le castagne dal fuoco ...
... il discorso è ovviamente slegato da questa specifica esigenza ... ma in generale, una read() che legga direttamente N bytes dal buffer circolare invece che leggere carattere a carattere e ritornare quando ha ricevuto N caratteri, sarebbe utilizzabile in modo asincrono e più veloce.

Come anticipato è però un discorso non correlato al caso specifico.

Guglielmo
Search is Your friend ... or I am Your enemy !

Standardoil

... il discorso è ovviamente slegato da questa specifica esigenza ... ma in generale, una read() che legga direttamente N bytes dal buffer circolare invece che leggere carattere a carattere e ritornare quando ha ricevuto N caratteri, sarebbe utilizzabile in modo asincrono e più veloce.

Come anticipato è però un discorso non correlato al caso specifico.

Guglielmo

non può essere asincrona, come farebbe a leggere N byte se nel buffer ce ne fossero solo N-1
Chiaramente dovrebbe abortire o aspettare, comunque non sarebbe asincrona
Prima legge di Nelson (che sono io): fai le stesse cose sempre alla stessa maniera, quegli errori li hai già corretti

Non bado a studenti, che vadano a copiare da un'altra parte

Se io ti domando e tu non mi rispondi vuol dire che non ti serve più

gpb01

#35
May 21, 2019, 02:05 pm Last Edit: May 21, 2019, 02:05 pm by gpb01
non può essere asincrona, come farebbe a leggere N byte se nel buffer ce ne fossero solo N-1
Chiaramente dovrebbe abortire o aspettare, comunque non sarebbe asincrona
Guarda che c'è una chiamata, NON bloccante, per sapere quanti bytes sono nel buffer ... quindi ... CERTO che sarbbe asincrona!

Guglielmo
Search is Your friend ... or I am Your enemy !

Maurotec

Quote
... il discorso è ovviamente slegato da questa specifica esigenza ... ma in generale, una read() che legga direttamente N bytes dal buffer circolare invece che leggere carattere a carattere e ritornare quando ha ricevuto N caratteri, sarebbe utilizzabile in modo asincrono e più veloce.
Sarebbe comoda da usare ma c'è da vedere se la gestione del ring buffer lo permette. Ad esempio cosa accade durante il tempo che la read copia la porzione di buffer verso la memoria di destinazione?

Il problema è che la read deve operare con gli interrupt disabilitati e per copiare 64 byte ci vuole più tempo che per copiarne uno.

Ciao.

gpb01

#37
May 21, 2019, 02:11 pm Last Edit: May 21, 2019, 02:20 pm by gpb01
Il problema è che la read deve operare con gli interrupt disabilitati e per copiare 64 byte ci vuole più tempo che per copiarne uno.
... a parte che un memcpy(), in assembler, su una MCU a 16 MHz è piuttosto veloce ;) , ma comunque stavamo parlando di leggere un int o un long ... 2 o 4 bytes ... e sarebbe sicuramemte gestibile :)

Codice della memcpy() ...

Code: [Select]
/* Copyright (c) 2002, 2007 Marek Michalkiewicz
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
   * Neither the name of the copyright holders nor the names of
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE. */

/* $Id: memcpy.S 1944 2009-04-01 23:12:20Z arcanum $ */

/** \file */
/** \ingroup avr_string
    \fn void *memcpy(void *dest, const void *src, size_t len)
    \brief Copy a memory area.

    The memcpy() function copies len bytes from memory area src to memory area
    dest.  The memory areas may not overlap.  Use memmove() if the memory
    areas do overlap.

    \returns The memcpy() function returns a pointer to dest.  */

#if !defined(__DOXYGEN__)

#include "macros.inc"

#define dest_hi r25
#define dest_lo r24
#define src_hi r23
#define src_lo r22
#define len_hi r21
#define len_lo r20

ASSEMBLY_CLIB_SECTION
.global _U(memcpy)
.type _U(memcpy), @function
_U(memcpy):
X_movw ZL, src_lo
X_movw XL, dest_lo
#if OPTIMIZE_SPEED
; 15 words, (14 + len * 6 - (len & 1)) cycles
sbrs len_lo, 0
rjmp .L_memcpy_start
rjmp .L_memcpy_odd
.L_memcpy_loop:
ld __tmp_reg__, Z+
st X+, __tmp_reg__
.L_memcpy_odd:
ld __tmp_reg__, Z+
st X+, __tmp_reg__
.L_memcpy_start:
subi len_lo, lo8(2)
sbci len_hi, hi8(2)
#else
; 11 words, (13 + len * 8) cycles
rjmp .L_memcpy_start
.L_memcpy_loop:
ld __tmp_reg__, Z+
st X+, __tmp_reg__
.L_memcpy_start:
subi len_lo, lo8(1)
sbci len_hi, hi8(1)
#endif
brcc .L_memcpy_loop
; return dest (unchanged)
ret
.L_memcpy_end:
.size _U(memcpy), .L_memcpy_end - _U(memcpy)

#endif /* not __DOXYGEN__ */

Guglielmo
Search is Your friend ... or I am Your enemy !

Standardoil

#38
May 21, 2019, 02:15 pm Last Edit: May 21, 2019, 02:16 pm by Standardoil
Guarda che c'è una chiamata, NON bloccante, per sapere quanti bytes sono nel buffer ... quindi ... CERTO che sarbbe asincrona!

Guglielmo
si, ma se devo fare io la chiamata, faccio anche il for di lettura...
In pratica tu mi dici che la readmultibyte è asincrona quando la chiamo all'istante giusto. ?? Controllato precedentemente con una available()?
questo non è asincrono, dato che la gestione tempi non solo c'è, ma pure a carico del programmatore
Asincrono sarebbe se un dispositivo hardware, configurabile, ricevesse nel suo buffer N byte e alzasse un interrupt quando serve. Ma se devo io controllare la available è solo una gran rottura
Prima legge di Nelson (che sono io): fai le stesse cose sempre alla stessa maniera, quegli errori li hai già corretti

Non bado a studenti, che vadano a copiare da un'altra parte

Se io ti domando e tu non mi rispondi vuol dire che non ti serve più

gpb01

#39
May 21, 2019, 02:19 pm Last Edit: May 21, 2019, 02:25 pm by gpb01
Ma se devo io controllare la available è solo una gran rottura
Guarda che funziona sempre così ...
... si lancia un processo (la ISR che legge i caratteri per conto suo), si interroga lo stato del processo (... che gira per conto suo) e, quando quel processo ha sufficenti dati da darmi, leggo il blocco ... durante tutto il tempo, faccio altre cose.

Si potrebbe fare anche di meglio, si potrebbe costruire la cosa (... tanto andrebbe fatta da zero dato che non c'è), in modo che, ricevuti gli N bytes che io mi aspetto, mi avvisa con un interrupt (... altro metodo largamente utilizzato).

Guglielmo
Search is Your friend ... or I am Your enemy !

Maurotec

Quote
parlando di leggere un int o un long ... 2 o 4 bytes ... e sarebbe sicuramemte gestibile :)
Ok, allora in ottica C++ basta aggiungere 2 read(); uint16_t read() e uint32_t read() che sono sicuramente più rapide di memcpy (anche se scritte in asm).


zoomx

Credo che bisogna considerare che il serial.write() di più byte verso PC funziona anche perché l'Atmega328 e i processori x86 sono entrambi little endian, altrimenti dall'altro lato bisogna tenere conto di quale byte arriva prima.

@Mauro93,
Si, siamo pazzi.

gpb01

#42
May 21, 2019, 03:13 pm Last Edit: May 21, 2019, 03:13 pm by gpb01
Ok, allora in ottica C++ basta aggiungere 2 read(); uint16_t read() e uint32_t read() che sono sicuramente più rapide di memcpy (anche se scritte in asm).
Concordo :D

Guglielmo
Search is Your friend ... or I am Your enemy !

docdoc

Concordo :D
E quindi direi: implementare una nuova classe che estende la Serial... ;)
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

gpb01

#44
May 21, 2019, 03:18 pm Last Edit: May 21, 2019, 03:18 pm by gpb01
E quindi direi: implementare una nuova classe che estende la Serial... ;)
Buon divertimento ... postaci il risultato :)

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up