Calculs Picaxiens

BESQUEUT

Senior Member
J'ai un montage qui suit la tension (et l'intensité) d'une source d'énergie.
Jusqu'à présent le Picaxe transmettait la valeur lu et c'est le programme du PC qui faisait la conversion en Volts (et en Ampères)
Je souhaite faire cette conversion sur le Picaxe et transmettre directement des milliVolts (et des milliAmpères)
La formule est la suivante :
V= readadc10 / 1024 * (VrefPlus - VrefMoins) + VrefMoins
Avec
VrefMoins = 0.63 V
VrefPlus = 4.98 V
et donc une différence de 4350 mV
que j'ai décomposé comme suit : 4350 =29*3*50

Dans PE, j'ai utilisé la formule suivante :
w7=readadc10
w8=w7*50+16/32*29+2/4*3+4/8+630

Puis j'ai comparé avec un calcul décimal fait avec Excel :
Code:
readadc10	Excel	   PE
0	        630,0	   630
1	        634,2	   636
2	        638,5	   638
3	        642,7	   644
4	        647,0	   647
5	        651,2	   652
6	        655,5	   654
7	        659,7	   660
8	        664,0	   665
9	        668,2	   668
10	        672,5	   674
		
512	      2805,0	 2805
		
1021	      4967,3	 4967
1022	      4971,5	 4972
1023	      4975,8	 4975
1024	      4980,0	 4980
Je fais appel à vos neurones :
Y a-t-il moyen de faire mieux ?
 

PieM

Senior Member
Y a-t-il moyen de faire mieux ?
A moins de faire le calcul sur 32bits, je ne vois pas trop ...
on peut améliorer les chose en faisant un calcul conditionnel:
pour les petites valeurs de w7 (<15) calculer w8= w7*4248/1000+630
Mais je ne comprends pas trop a quoi va servir un calcul plus précis puisque la valeur en mV ne sera jamais connue qu'à 4mV de résolution ?
 

BESQUEUT

Senior Member
A moins de faire le calcul sur 32bits, je ne vois pas trop ...
on peut améliorer les chose en faisant un calcul conditionnel:
pour les petites valeurs de w7 (<15) calculer w8= w7*4248/1000+630
Mais je ne comprends pas trop a quoi va servir un calcul plus précis puisque la valeur en mV ne sera jamais connue qu'à 4mV de résolution ?
Merci de vous pencher sur ce problème.
Votre dernière réflexion est très juste et cette façon de calculer est en pratique suffisante.
C'est juste que mon application est sensible aux variations de tensions. En l&#8217;occurrence, une tension qui croit régulièrement devrait avoir des incréments de 4 ou 5 mv. (4350/1024=4.248)
Hors j'observe des variations de 6, puis de 2mv qui sont purement artificielles (dues au calcul) tout en restant dans la tolérance.
J'ai également envisagé de faire les calculs en 32 bits (par paquets de 8). C'est faisable, mais l'écriture de cette bibliothèque est un travail conséquent (addition, soustraction, multiplication et division), non justifié pour cette seule application.
Je retiens néanmoins l'idée du calcul conditionnel, qui devrait tout aussi bien fonctionner en divisant tout par 8 !
La formule serait donc applicable jusqu'à 120 :
w8=w7 * 531 /125 + 630
Comme je l'ai fait dans la "grosse" formule, on peut limiter les conséquences de l'arrondi à l'entier inférieur en ajoutant 0,5 ce qui donne :
w8=w7 * 531 + 62 /125 + 630
Merci

Code:
w7    Excel	PE	PieM
0	630,0	 630	630
1	634,2	 636	634
2	638,5	 638	638
3	642,7	 644	643
4	647,0	 647	647
5	651,2	 652	651
6	655,5	 654	655
7	659,7	 660	660
8	664,0	 665	664
9	668,2	 668	668
10	672,5	 674	672
			
119	1135,5	1136	1136
120	1139,8	1141	1140
121	1144,0	1144	1144
Effectivement : les calculs sont bien plus "propres".
 
Last edited:

PapyJP

Senior Member
Je ne suis pas sûr d' avoir bien compris le Pb !
S' agit-il de transferer W7 au PC avec toute la précision ?
Si oui, pourquoi ne pas transmettre W7 sous forme binaire .
La conversion décimal-binaire est facile à réaliser par division successives de W7 par 2 jusqu'à ce que le quotient soit égal à zéro.
et en calculant le reste à chaque division.

=Exemple de calcul du reste:
25/2 = 14
Reste = 25 - ( 2 * 14 ) = 1

=Exemple de conversion décimal-binaire
25/2 = ( 2 *12 ) +1
12/2 = ( 2 *6 ) +0
6/2 = ( 2 *3 ) +0
3/2 = ( 2 * 1 ) +1
1/2 = 0 +1
Le binaire résultant est donc 11001 ( = 25 )
Notez que le nombre binaire résultant s' obtient en écrivant le premier reste à la position du bit de plus faible poids.
 
Last edited:

PieM

Senior Member
qui devrait tout aussi bien fonctionner en divisant tout par 8 !
Heu ... :eek: justement j'étais en train de faire apprendre les caractères de divisibilité à ma petite fille ! Ne lui répétez pas !

@PapyJP

Le problème mentionné en #1 est avant tout de faire le calcul par le Picaxe.
Sinon, en quoi changer de système de numération apporte de la "précision" ?
 

BESQUEUT

Senior Member
S' agit-il de transferer W7 au PC avec toute la précision ?
Oui, mais en clair, CAD en millivolts
Le but est de pouvoir soit récupérer les données avec un programme dédié qui fait des traitements complémentaires et de l'archivage, soit lire l'info avec un terminal (genre Minitel...) ou écran LCD.
Jusqu'à présent, je récupérais directement la valeur lue (entre 0 et 1023) et donc avec toute la précision. La conversion était faite sur le PC, en VB et en arithmétique flottante. Avec le Picaxe, il faut faire le calcul avec des nombres entiers sur 16 bits ce qui est loin d'être évident si on souhaite conserver un maximum de précision.
 
Last edited:

PapyJP

Senior Member
Le problème mentionné en #1 est avant tout de faire le calcul par le Picaxe
Ok ! je n' avais pas, comme je le craignais, bien saisi le Pb

@ BESQUEUT
Je suis d' accord sur l' équation de la droite : Y(mV) = (4,248) * X + 630
J' ai cherché sans trouver de méthode qui donne d' aussi bons résultats que les vôtres.
Aie! mes neurones .........

N' y a-t-il pas en #1 faute de frappe dans l' expression de w8 ? ( Si l' on fait w7 = 0 on ne trouve pas w8 = 630 )
 
Last edited:

BESQUEUT

Senior Member
N' y a-t-il pas en #1 faute de frappe dans l' expression de w8 ? ( Si l' on fait w7 = 0 on ne trouve pas w8 = 630 )
Ne pas oublier que sur un Picaxe les opérations sont effectuées de la gauche vers la droite, sans préséance des opérateurs...
Le Picaxe effectue :
w8=(w7 * 531 + 62) /125 + 630
le +62 est la moitié de 125 (en nombre entier...)
Dans la division entière, le résultat est arrondi à l'entier inférieur, ce qui entraîne une minoration systématique du résultat.
En ajoutant 0,5 avant chaque division intermédiaire, on fait un arrondi à l'entier le plus proche (aléatoirement au-dessus ou au-dessous) et le résultat n'est pas systématiquement biaisé.
Mais comment ajouter 0,5 à un nombre entier ?
Ben, il suffit d'ajouter la moitié du diviseur avant de faire la division...
 
Last edited:

BESQUEUT

Senior Member
J' ai cherché sans trouver de méthode qui donne d' aussi bons résultats que les vôtres.
L'inconvénient est qu'il faut cogiter en cas de changement de valeurs de Vref+ et Vref-
Hors le TL431 qui me servait de référence vient de passer de vie à trépas... Je vais donc devoir remplacer avec ce que j'ai sous la main, à savoir un TL7705.
Et probablement mettre au point un calcul sur 32 bits, qui marche à tous les coups, et avec une précision à l'unité près...
Finalement, la multiplication n'est pas si terrible ; et la division par 1024 est triviale.
Je publierai dès que ce sera au point, mais ce WE, je suis full time...
 

marks

Senior Member
Salut Besqueut,
Vous pouvez également essayer d'utiliser un mot de poids fort **
W7 =W8 * 48 ** 58 000 + 6300 'convertir par exemple 0 = 6300 et 1024 = 49800

J'aurais pensé que 1023 aurait été de 49800
Si c'est le cas changer mot de poids fort de 58 057 **
 

BESQUEUT

Senior Member
Vous pouvez également essayer d'utiliser un mot de poids fort **
Merci beaucoup : j'avais complètement oublié cette possibilité, qui revient à faire la multiplication sur 32 bits.
Je teste ça ASAP.
J'aurais pensé que 1023 aurait été de 49800
Il y a beaucoup d'exemples qui divisent par 1023 au lieu de 1024. Si on lit correctement la documentation du PIC, c'est une erreur qui introduit une dérive de l'ordre de 0,1 % sur les mesures. Je suppose que beaucoup de personnes ne s'en rendent pas compte. Mais sur le principe, c'est faux. En effet, il y a bien 1024 valeurs possibles qui vont de 0 à 1023.
Quand aux tensions correspondantes, il s'agit d'une fonction en escalier décalée d'un quart d'intervalle, mais il y a bien 1024 marches.
 

PapyJP

Senior Member
En effet, il y a bien 1024 valeurs possibles qui vont de 0 à 1023
En effet, c' est le fameux problème des piquets et des intervalles que nous posons à nos chères têtes blondes ( aux autres aussi d' ailleurs... ) pour clore le bord d' un champ.
Si le premier piquet est noté 0 ( zéro ) et le dernier 1024, il y a 1025 piquets et donc 1024 intervalles ( de 0 à 1023 )!

Merci pour le clin d' oeil au Minitel que j' utilise toujours comme terminal.
 

PapyJP

Senior Member
Une piste:
1/ je pars du principe que les nombres, au niveau du Picaxe, sont des entiers " word " <= 2E16 ( <= 65536 ) transférables au PC.
2/ l' équation de la droite de conversion est y = a*x + b soit y = 4,248 * x + 630 dans votre exemple
==> 1000*y = 4248*x + 630000
3/ Je décompose 4248 en facteurs premiers : 4248 = 2E3 * 3E2 * 59 = 8 *9 *59 = 8 * 531
4/ je transmets au PC : x = 8 * W7 ( x < 65536 qqsoit W7 )
5/ Le PC doit faire un calcul simple, dans un tableur par exemple, sans passer par VB :
y = ((x / 1000 ) * 531 ) + 630
On obtient trois décimales aprés les mV !
Cette méthode s' applique qqsoient les coef a et b de la droite donc qqsoient les Vref
Vérif:
W7=512
x = 8 * W7 = 4096
y = (( x /1000)*531) + 630 = 2804,976 mV

Commentaires bien venus
 
Last edited:

PapyJP

Senior Member
Bémol en #14
En toute rigueur, la méthode est applicable si ( 1000 * a ) n' est pas premier ( pas de bol dans ce cas ! ) et si l' on a au moins un des facteurs de la décomposition qui soit inférieur à 65536/1024.
On peut combiner les facteurs premiers.
Ainsi on aurait pu prendre : 4248 = 8*3*3*59 = 24 *177 puisque 24*1024 < 65536
 
Last edited:

PieM

Senior Member
PapyJP:
Super ! Donc avec une résolution de 4 mV à l'entrée, on a un résultat à 1 µV de résolution ?

En tout état de cause, bien que comme déjà dit ce n'est pas le but poursuivi, si le calcul doit être fait par le PC, je ne vois pas en quoi il est plus compliqué de faire directement le calcul de (readadc10)*4.248+630

Besqueut;

Une méthode que je n'ai jamais utilisée car je préfère prendre des µC traitant les nb en FPU pour des appareils un peu pointus, c'est le Q16.16
Une bibliothèque Picaxe a été écrite par Jeremy Leach
Pour le fun:

La doc: View attachment FractionalMaths.pdf

La bibliothèque: View attachment FractionalMathsV1g.bas
 

BESQUEUT

Senior Member
Merci pour ces liens que je vais conserver précieusement, au cas où...
Pour le moment, puisque les Picaxes savent faire la multiplication sur 32 bits, autant en profiter. (voir #11)
Pour la division, tant qu'il s'agit d'une puissance de 2, c'est trivial (donc en particulier pour 1024)
On est bien d'accords : la précision reste de 4mV. Mais autant que faire se peut, je préfère éviter d'ajouter un aléa de +-3mV...
 

BESQUEUT

Senior Member
y = ((x / 1000 ) * 531 ) + 630
Commentaires bien venus
Cette décomposition a été proposée en #3.
Si on fait le calcul sur un PC, autant transmettre directement la valeur lue par readADC10.
Le but est de faire le calcul sur le Picaxe pour transmettre directement une valeur en V ou en mV, lisible avec le terminal par exemple.
L'autre problème est qu'en cas de remplacement ou de ré-étalonnage de la référence, il faut refaire le programme.
Avec les math sur 32 bits, la formule est universelle tout en restant exacte.
 

BESQUEUT

Senior Member
Bon alors voilà le code pour la mise à l'échelle sur 32 bits (hors addition de VrefMoins)
Code:
#simspeed 0


main:
for w8=0 to 4
   	w9=4350
	gosub volts
next w8

for w8=127 to 129
   	w9=4350
	gosub volts
next w8

for w8=1015 to 1024
   	w9=4350
	gosub Volts
next w8

for w8=65534 to 65535
   	w9=32768
	gosub Volts
next w8

for w8=65534 to 65535
   	for w9=65534 to 65535
		gosub Volts
	next w9
next w8
end

' Volts= w8*w9/1024        arrondi à l'entier le plus proche
Volts:
	w0=w8*w9
	w1=w8**w9
	w2=w0

	b9=bit9
	
	bit0=bit10
	bit1=bit11
	bit2=bit12
	bit3=bit13
	bit4=bit14
	bit5=bit15
	bit6=bit16
	bit7=bit17
	bit8=bit18
	bit9=bit19
	bit10=bit20
	bit11=bit21
	bit12=bit22
	bit13=bit23
	bit14=bit24
	bit15=bit25
	
	if b9=1 then	' arrondi
		inc w0
	endif
'	w0=w0+630
	
	sertxd (#w8," x ",#w9," = ", #w1,":",#w2,"  ",#w0," mV",13,10)
return
Les résultats sont parfaits dans la plage de mesure de ReadADC
Code:
W8	W9	W1	W0	mV      Excel
0	4350	0	0	0	0,00
1	4350	0	4350	4	4,25
2	4350	0	8700	8	8,496
3	4350	0	13050	13	12,74
4	4350	0	17400	17	16,99
					
127	4350	8	28162	540	539,50
128	4350	8	32512	544	543,75
129	4350	8	36862	548	548,00
					
1015	4350	67	24338	4312	4311,77
1016	4350	67	28688	4316	4316,02
1017	4350	67	33038	4320	4320,26
1018	4350	67	37388	4325	4324,51
1019	4350	67	41738	4329	4328,76
1020	4350	67	46088	4333	4333,01
1021	4350	67	50438	4337	4337,26
1022	4350	67	54788	4342	4341,504
1023	4350	67	59138	4346	4345,75
1024	4350	67	63488	4350	4350,00
Toutefois, j'ai poussé à fond la multiplication sur 32 bits, et surprise :
- à partir d'un moment la multiplication merde !
==> j'ai mis une colonne spéciale pour ce que calcule Excel
à savoir (w7*w8) modulo 65536
Code:
W8	W9	W1	W0        w0(Excel)
65534	32768	32767	0         0
65535	32768	32767	32768  32768

65534	65534	65532	598       4
65534	65535	65533	375       2
65535	65534	65533	438       2
65535	65535	65534	438       1
Impossible de savoir pour le moment si c'est le simulateur qui merde,
ou si le problème est reproductible sur un Picaxe.
En toute logique
65534*65535 devrait donner la même chose que
65535*65534...
En tout cas, à mon humble avis, il y a un gros bug dans la multiplication...
 
Last edited:

marks

Senior Member
J'ai beaucoup apprécié votre programme reall bon test!
Code:
#simspeed 0


main:
for w8=0 to 4
   	
	gosub volts
next w8

for w8=127 to 129
   	
	gosub volts
next w8

for w8=1015 to 1024
   	
	gosub Volts
next w8


end


Volts:
	w0=w8*48**58000+5/10
	
'	w0=w8*48**58000+6305/10
	
	sertxd (#w8,"  ",#w0," mV",13,10)
return
 

BESQUEUT

Senior Member
J'ai beaucoup apprécié votre programme reall bon test!
Code:
Volts:
	w0=w8*48**58000+5/10
	
'	w0=w8*48**58000+6305/10
	
	sertxd (#w8,"  ",#w0," mV",13,10)
return
Oui mais... il faut refaire le programme chaque fois que w9 change...
D'autre, part, avez-vous testé les multiplications suivantes :
65534*65535
65535*65534
Avec le simulateur, le résultat me semble erroné.

Ok, but... I have to rewrite program each time w9 change...
And, did you test following operations :
65534*65535
65535*65534
With simulator, results seems to be erroneous...
 

BESQUEUT

Senior Member
Voici une version plus courte, mais peut-être moins explicite au niveau du décalage des bits...
Il y a en commentaire une version encore plus optimisée, mais avec >> qui n'est disponible que sur certains Picaxes.
Code:
Volts:
	w0=w8*w9
	w1=w8**w9

	b9=bit9
	
'	w0=w0>>10		' only for X2 Picaxes
'	w0=w1<<6 or w0

	w0=w0/1024
	w0=w1*64 or w0
	
	if b9=1 then	' arrondi
		inc w0
	endif
'	w0=w0+630
	
	sertxd (#w8," x ",#w9," => ",#w0," mV",13,10)
return
 

BESQUEUT

Senior Member
Je n'ai rien compris à la formule de Mark !
Le fait est que le résultat est bon, mais semble décalé vers le haut.
Ayé : j'ai pigé :
48*5800/65536
est bien la même chose que:
4350/1024
Sauf que la multiplication par 48 tient dans les 16 premiers bits,
et la deuxième (*5800) donne un résultat dans le "mot de poids fort", CAD les 16 bits suivants.
Le problème, c'est qu'il faut trouver de nouveaux coefficients en cas de ré-étalonnage.
Code:
W8	W9	mV	Mark	Excel
0	4350	0	0	0,000
1	4350	4	4	4,248
2	4350	8	8	8,496
3	4350	13	14	12,744
4	4350	17	18	16,992
						
127	4350	540	541	539,502
128	4350	544	545	543,750
129	4350	548	549	547,998
						
1015	4350	4312	4313	4311,768
1016	4350	4316	4316	4316,016
1017	4350	4320	4320	4320,264
1018	4350	4325	4326	4324,512
1019	4350	4329	4330	4328,760
1020	4350	4333	4333	4333,008
1021	4350	4337	4337	4337,256
1022	4350	4342	4343	4341,504
1023	4350	4346	4347	4345,752
1024	4350	4350	4350	4350,000
Comment expliquer une telle précision alors que les facteurs n'ont que 2 chiffres significatifs ?
Sans doute un hasard du au fait que 4350 est un multiple de 10 : du coup les coefficients choisis par Mark ont en fait 3 chiffres significatifs : 48,0 et 580(0)

Quelle serait la formule si w9=4349 ?
 
Last edited:

marks

Senior Member
Salut
vos résultats sont différents des miens que vous utilisez le programme latsest picaxe
Code:
#simspeed 0


main:
for w8=0 to 4
   	
	gosub volts
next w8

for w8=127 to 129
   	
	gosub volts
next w8

for w8=1015 to 1024
   	
	gosub Volts
next w8


end


Volts:
	w0=w8*48**58000+5/10
	
'	w0=w8*48**58000+6305/10
	
	sertxd (#w8,"  ",#w0," mV",13,10)
return

'results


'sertxd output - baud 4800,n,8,1
0  0 mV


'sertxd output - baud 4800,n,8,1
1  4 mV


'sertxd output - baud 4800,n,8,1
2  8 mV


'sertxd output - baud 4800,n,8,1
3  13 mV


'sertxd output - baud 4800,n,8,1
4  17 mV


'sertxd output - baud 4800,n,8,1
127  540 mV


'sertxd output - baud 4800,n,8,1
128  544 mV


'sertxd output - baud 4800,n,8,1
129  548 mV


'sertxd output - baud 4800,n,8,1
1015  4312 mV


'sertxd output - baud 4800,n,8,1
1016  4316 mV


'sertxd output - baud 4800,n,8,1
1017  4320 mV


'sertxd output - baud 4800,n,8,1
1018  4325 mV


'sertxd output - baud 4800,n,8,1
1019  4329 mV


'sertxd output - baud 4800,n,8,1
1020  4333 mV


'sertxd output - baud 4800,n,8,1
1021  4337 mV


'sertxd output - baud 4800,n,8,1
1022  4342 mV


'sertxd output - baud 4800,n,8,1
1023  4346 mV


'sertxd output - baud 4800,n,8,1
1024  4350 mV
Code:
#simspeed 0


main:
for w8=0 to 4
   	w9=4350
	gosub volts
next w8

for w8=127 to 129
   	w9=4350
	gosub volts
next w8

for w8=1015 to 1024
   	w9=4350
	gosub Volts
next w8

for w8=65534 to 65535
   	w9=32768
	gosub Volts
next w8

for w8=65534 to 65535
   	for w9=65534 to 65535
		gosub Volts
	next w9
next w8
end

' Volts= w8*w9/1024        arrondi à l'entier le plus proche
Volts:
	w0=w8*w9
	w1=w8**w9
	w2=w0

	b9=bit9
	
	bit0=bit10
	bit1=bit11
	bit2=bit12
	bit3=bit13
	bit4=bit14
	bit5=bit15
	bit6=bit16
	bit7=bit17
	bit8=bit18
	bit9=bit19
	bit10=bit20
	bit11=bit21
	bit12=bit22
	bit13=bit23
	bit14=bit24
	bit15=bit25
	
	if b9=1 then	' arrondi
		inc w0
	endif
'	w0=w0+630
	
	sertxd (#w8," x ",#w9," = ", #w1,":",#w2,"  ",#w0," mV",13,10)
return







'sertxd output - baud 4800,n,8,1
0 x 4350 = 0:0  0 mV


'sertxd output - baud 4800,n,8,1
1 x 4350 = 0:4350  4 mV


'sertxd output - baud 4800,n,8,1
2 x 4350 = 0:8700  8 mV


'sertxd output - baud 4800,n,8,1
3 x 4350 = 0:13050  13 mV


'sertxd output - baud 4800,n,8,1
4 x 4350 = 0:17400  17 mV


'sertxd output - baud 4800,n,8,1
127 x 4350 = 8:28162  540 mV


'sertxd output - baud 4800,n,8,1
128 x 4350 = 8:32512  544 mV


'sertxd output - baud 4800,n,8,1
129 x 4350 = 8:36862  548 mV


'sertxd output - baud 4800,n,8,1
1015 x 4350 = 67:24338  4312 mV


'sertxd output - baud 4800,n,8,1
1016 x 4350 = 67:28688  4316 mV


'sertxd output - baud 4800,n,8,1
1017 x 4350 = 67:33038  4320 mV


'sertxd output - baud 4800,n,8,1
1018 x 4350 = 67:37388  4325 mV


'sertxd output - baud 4800,n,8,1
1019 x 4350 = 67:41738  4329 mV


'sertxd output - baud 4800,n,8,1
1020 x 4350 = 67:46088  4333 mV


'sertxd output - baud 4800,n,8,1
1021 x 4350 = 67:50438  4337 mV


'sertxd output - baud 4800,n,8,1
1022 x 4350 = 67:54788  4342 mV


'sertxd output - baud 4800,n,8,1
1023 x 4350 = 67:59138  4346 mV


'sertxd output - baud 4800,n,8,1
1024 x 4350 = 67:63488  4350 mV


'sertxd output - baud 4800,n,8,1
65534 x 32768 = 32767:0  65472 mV


'sertxd output - baud 4800,n,8,1
65535 x 32768 = 32767:32768  65504 mV


'sertxd output - baud 4800,n,8,1
65534 x 65534 = 65532:4  65280 mV


'sertxd output - baud 4800,n,8,1
65534 x 65535 = 65533:2  65344 mV


'sertxd output - baud 4800,n,8,1
65535 x 65534 = 65533:2  65344 mV


'sertxd output - baud 4800,n,8,1
65535 x 65535 = 65534:1  65408 mV
 

BESQUEUT

Senior Member
vos résultats sont différents des miens que vous utilisez le programme latsest picaxe
Oups : autant pour moi !
J'avais oublié de retirer le code d'arrondi, du coup l'arrondi se faisait deux fois ...
Code:
	if b10=1 then	' arrondi
		inc w0
	endif
J'en profite pour vous demander quelle serait votre formule pour w9=4349 ?
Et quel est votre avis sur les opérations suivantes :
65534*65535
65535*65534

OOps : you are true, I did forget to remove code for rounding...

By the time, what will be your formula for w9=4349 ?
And, what do you think about :
65534*65535
65535*65534
 

marks

Senior Member
Hi ,
hope this helps.
I thought the values returned into w1 w2 when I tested were correct.
espérons que cette aide.
Je pensais que les valeurs retournées dans w1 w2 lorsque j'ai testé étaient correctes


examples
4350/1024*65535/64+1=4350
4349/1024*65535/48+1=5799

w0=w0*8**34792 ' 4349/1024*65535/8+1=34792


'sertxd output - baud 4800,n,8,1
65534 x 65535 = 65533:2 65344 mV

'sertxd output - baud 4800,n,8,1
65535 x 65534 = 65533:2 65344 mV

'sertxd output - baud 4800,n,8,1
65535 x 65535 = 65534:1 65408 mV
 
Last edited:

BESQUEUT

Senior Member
Très étrange !
Vos résultats sont corrects, mais je n'obtiens pas la même chose :
Code:
#simspeed 0


main:

for w8=65534 to 65535
   	for w9=65534 to 65535
		gosub Volts
	next w9
next w8
end

' Volts= w8*w9/1024        arrondi à l'entier le plus proche
Volts:
	w0=w8*w9
	w1=w8**w9
	w2=w0

	b9=bit9
	
	bit0=bit10
	bit1=bit11
	bit2=bit12
	bit3=bit13
	bit4=bit14
	bit5=bit15
	bit6=bit16
	bit7=bit17
	bit8=bit18
	bit9=bit19
	bit10=bit20
	bit11=bit21
	bit12=bit22
	bit13=bit23
	bit14=bit24
	bit15=bit25
	
	if b9=1 then	' arrondi
		inc w0
	endif
	
	sertxd (#w8," x ",#w9," = ", #w1,":",#w2,"  ",#w0," mV",13,10)
return



'sertxd output - baud 9600,n,8,1
65534 x 65534 = 65532:0  65280 mV

'sertxd output - baud 9600,n,8,1
65534 x 65535 = 65533:65280  65408 mV

'sertxd output - baud 9600,n,8,1
65535 x 65534 = 65533:65408  65408 mV

'sertxd output - baud 9600,n,8,1
65535 x 65535 = 65534:65408  65472 mV
PE version 5.4.0 Windows 7 64 bits
D'autres peuvent-ils vérifier ?
 

BESQUEUT

Senior Member
Voici un programme qui ne teste que la multiplication :
Code:
#simspeed 0


main:
for w8=32767 to 32769
   	for w9=32767 to 32769
		w0=w8*w9
		sertxd (#w8," x ",#w9," = ",#w0,13,10)
	next w9
next w8

for w8=65534 to 65535
   	for w9=65534 to 65535
		w0=w8*w9
		sertxd (#w8," x ",#w9," = ",#w0,13,10)
	next w9
next w8
end

'sertxd output - baud 9600,n,8,1
32767 x 32767 = 1

'sertxd output - baud 9600,n,8,1
32767 x 32768 = 32768

'sertxd output - baud 9600,n,8,1
32767 x 32769 = 65535

'sertxd output - baud 9600,n,8,1
32768 x 32767 = 32768

'sertxd output - baud 9600,n,8,1
32768 x 32768 = 0

'sertxd output - baud 9600,n,8,1
32768 x 32769 = 32768

'sertxd output - baud 9600,n,8,1
32769 x 32767 = 65535

'sertxd output - baud 9600,n,8,1
32769 x 32768 = 32768

'sertxd output - baud 9600,n,8,1
32769 x 32769 = 1

'sertxd output - baud 9600,n,8,1
65534 x 65534 = 1

'sertxd output - baud 9600,n,8,1
65534 x 65535 = 1

'sertxd output - baud 9600,n,8,1
65535 x 65534 = 1

'sertxd output - baud 9600,n,8,1
65535 x 65535 = 1
Il semble qu'à partir d'une certaine valeur, le calcul ne se fasse plus et que w0 reste bloqué sur la dernière valeur calculée !
 

BESQUEUT

Senior Member
time to update pe version 5.5.5
OK : c'est bon maintenant. OK : that is good now !
w0=w0*48*57987+5/10 '4349.0
Je suppose que vous voulez dire :
I suppose you mean : w0=w8*48**57987+5/10
Très impressionnant ! Very impressive !

Donc : So :
wo=w8*48**A+5/10

Où : where :
A= w9*655360/1024/48 = w9*40/3
pour w9=4349 A=57987
pour w9=4350 A=58000
pour w9=4351 A=58013

Thank you very much, dear Mark. (Bon, amis francophiles : je traduis pas là...)

En fait, cette formule est strictement équivalente au programme #22 (d'où les résultats identiques)
Mais ça tient en une seule ligne. Chapeau bas !
Et je confirme #23 : il faut voir dans le terme 58000 5 chiffres significatifs, comme dans 57987.
 
Last edited:

PapyJP

Senior Member
Sûrement admirable, géant, moins gourmand en lignes de code que mes Pics en assembleur ( faudrait comparer quand même la vitesse d' éxécution ... ).
Mes neurones ( ceux qui me restent et ceux qui, parmi eux, sont encore fonctionnels ) ont beaucoup de mal à suivre. Mais je m' accroche !

Que représente, dans votre code ci-dessous, le signe " x " ( pas un symbole math en Basic ) ?
Code:
32767 x 32767 = 1
32767 x 32768 = 32768
32767 x 32769 = 65535
32768 x 32767 = 32768
32768 x 32768 = 0
32768 x 32769 = 32768
32769 x 32767 = 65535
32769 x 32768 = 32768
32769 x 32769 = 1
65534 x 65534 = 1
65534 x 65535 = 1
65535 x 65534 = 1
65535 x 65535 = 1
Pourquoi les cinq dernières lignes sont-elles toutes égales à 1 ?

@PieM
En #26, on est à 10 nanoVolts de résolution. Vous ne réagissez pas ( cf #16 ) ?
 

BESQUEUT

Senior Member
Que représente, dans votre code ci-dessous, le signe " x " ( pas un symbole math en Basic ) ?
Pourquoi les cinq dernières lignes sont-elles toutes égales à 1 ?
le "x" est juste une représentation de la multiplication dans un sertxd. Comprendre "*"
Les 4 dernières lignes sont des résultats erronés dus à un bug de PE, corrigé dans la dernière version (voir #26).
 

PieM

Senior Member
@ PapyJP

@PieM
En #26, on est à 10 nanoVolts de résolution. Vous ne réagissez pas ( cf #16 ) ?
Il y a confusion: en 26 il ne s'agit que d'exemple de calcul sur 32bits sans rapport avec une unité. Si le mV est resté , ce n'est que le résultat du sertxd (#w8," x ",#w9," = ", #w1,":",#w2," ",#w0," mV",13,10)

Le calcul sur 32 bits permet de ne pas perdre des chiffres significatifs lors du calcul, mais en aucun cas n'augmente une résolution des valeurs discrètes de l'entrée .
 

BESQUEUT

Senior Member
Le calcul sur 32 bits permet de ne pas perdre des chiffres significatifs lors du calcul, mais en aucun cas n'augmente une résolution des valeurs discrètes de l'entrée .
Ce qui est déjà une bonne chose, surtout vu la possibilité d'utiliser **
Pour ceux qui souhaiteraient tirer le maximum de résolution, voici une AN (Application Note) pour un autre µcontrôleur, mais qui est applicable à n'importe quel ADC.
Pas sur que l'on puisse réellement gagner 4 bits, mais 2, ça me semble possible.
http://www.atmel.com/Images/doc8498.pdf
Il y a tout de même deux conditions essentielles :
- la tension à mesurer doit rester stable pendant l'échantillonage,
- il doit y avoir un peu de bruit (et au besoin, il faut en ajouter !)
Je suis en train de tester. Mais le calcul de la moyenne d'une série de valeurs me semble difficile à réaliser autrement qu'en 32 bits. Je vais ouvrir un nouveau thread sur le sujet.
 

PapyJP

Senior Member
J' ai pas tout compris ( as usual ! ).

1/ Le manuel 2 précise ( pour tous les Picaxes, du 08M au 20X2 ):
SERTXD ({#}data,{#}data...)
- Data are variables/constants (0-255) which provide the data to be output.

Or vous écrivez ( en #34 par exemple )
sertxd (...#w8,....,#w9,...,#w1,...
Vous transmettez donc des mots (0-65535)
Faut-il corriger la syntaxe dans le manuel 2 ?

2/ Soit à effectuer une multiplication dans un Picaxe et à afficher le résultat sur un terminal qui ne possède pas de fonction de calcul ( lcd, Minitel,...) ou que l' on ne veuille pas utiliser cette fonction.
C' est bien le Pb posé ?

Je veux effectuer 12345 * 60
Code:
'A= 12345 * 60 = 740700
w8=12345
w9=60

w0=w8*w9
w1=w8**w9
La simulation me donne :
b0=92
b1=77
b2=11
b3=0
Donc
A=b2*65536 + (b1*256)+b0 = 740700
... l'erreur est juste ! Ok.

Maintenant je veux afficher le résultat, A.
Je peux transmettre les bx à un terminal mais il faudra bien que ce terminal effectue le calcul pour afficher A !
Il y a une siouxerie dans votre programme que je ne trouve pas.
Merci d' éclairer mon terminal !!!!!!!!!!
 

PieM

Senior Member
Data are variables/constants (0-255) which provide the data to be output.
Oui, c'est vrai que ça peut prêter à confusion ...
En fait data (sans #) est effectivement un nombre entre 0 et 255. Il correspond à la valeur ASCII qui est comprise par le terminal.
13 est vu comme un CR et 10 comme LF.
par contre le # transforme la variable qui suit en ses composantes (chiffres) sous forme ASCII

si w1 = 65230, #w1 est équivalent à "65230" qui va transmettre le code ascii de 6, de 5, de 2 etc ....

Par contre dans votre exemple, le nombre A = 740700 n'existe pas en tant que tel dans le Picaxe qui n'accepte que des variable 16 bits au maxi. donc vous ne pourrez pas afficher cette valeur en tant que nombre.
Avec d'autres µC c'est par contre possible.

les calculs sur 32 bits ne sont que des résultats intermédiaires.
 

PapyJP

Senior Member
1/ Oui, c'est vrai que ça peut prêter à confusion ...
2/Par contre dans votre exemple, le nombre A = 740700 n'existe pas
1/ Voulez-vous dire que dans
SERTXD ({#}data,{#}data...)
- Data are variables/constants (0-255) which provide the data to be output.

Les " # " entre accolades sont ' optionnelles '; si on ne les mets pas data est un byte, si on les mets data est un word ?

2/ Dans mon exemple, au niveau du Picaxe, je n' ai que w8=12345 et w9=60 ( voir mon code )
Il me semble que le Pb reste entier !
Merci de votre réponse rapide
 

PieM

Senior Member
Non ! relisez ce que j'ai écrit :
#variable transforme cette variable byte ou word en une suite de codes ASCII transmis par le sertxd ou le serout.

Vous devriez faire quelques petites manip avec PE et le simulateur.
essayez sertxd ( "A", 65 , #65)

2/ Dans mon exemple, au niveau du Picaxe, je n' ai que w8=12345 et w9=60 ( voir mon code )
Il me semble que le Pb reste entier
Si votre problème est d'afficher le résultat de 12345 * 60 je vous ai répondu. Ce résultat n'existe pas en tant que variable dans le picaxe qui ne connait pas les variable en 32 bits
 

PapyJP

Senior Member
#variable transforme cette variable byte ou word en une suite de codes ASCII
Ok.
J' en conclue
1/ que, dans une instruction sertxd, le " # " est toujours nécessaire que l' on transfère un byte ou un word ( pour qu'il soit transmis sous la forme d' une suite ASCII ).

2/ que l' article ' sertxd ' du manuel 2 a besoin d' être mis à jour ( Suppression des accolades dans le § ' sertxd ' et précision sur byte et word ).
Ai-je bien compris ?
Je ferai les manips que vous me proposez.
 
Top