vazeri / WSPREncode

WSPR Encoder modified Library for Arduino
GNU General Public License v3.0
1 stars 0 forks source link

Modificar protocolo WSPR #4

Open vazeri opened 6 years ago

vazeri commented 6 years ago

Las funciones “wspr_encode, wspr_message_prep” etc sean modificadas para que su parámetro tipo char array [ ] sea en cambio int array [ ] sin que perjudique el funcionamiento global de la función.

Alternativa:

O sino, crear una variable tipo int “number” y que sea insertada en la variable char “Call” utilizando 3 posiciones de su array [ ] con una conversión de valor de base 10 a base 36. Es decir si number== 2040, el char call contenga los primeros 3 elementos: “ 1K0” y el resto ‘A,B,C,D,E’ fijo, en el mismo arreglo call []. Luego se debe hacer el proceso inverso, a partir del valor call=’1,K,0,A,B,C,D,E’ escribir en otra variable int numer2, el valor original 2040.

Ayuda: se pueden utilizar las funciones itoa y strtol de la librería stdlib.h para insertar string en un int y viceversa.

vazeri commented 6 years ago

Hay que establecer un entorno de trabajo para poder debuggear el problema, lo tengo como pendiente, de manera temporal estaré compilando en linea utilziando https://www.onlinegdb.com

vazeri commented 6 years ago

Requiero mas detalle del problema, entiendo lo que se pretende hacer sin embargo no encuentro logica en el porque hacerlo, sin embargo es posible reemplazar el apuntador por uno que contenga los caracteres char

¿Cual es la razon por la cual se requiere un numero base 36 en tres posiciones de memoria distintas?


Una primera aproximación al problema seria el siguiente codigo

char characters[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 0}; // last one is NULL terminator

int replace = 1;
cout << "Enter the number you want to replace with X: ";
cin >> replace;

assert(replace > 0 && replace < 10); // or otherwise check validity of input

characters[replace - 1] = 'X';

// print the string
cout << characters;

// if the user entered 5, it would print
// 1234X6789
vazeri commented 6 years ago

La redacción del problema original es altamente confusa llevo varias horas tratando de interpretarla, tratare de simplificar y revisar qué efectos (teóricos) tendría el hacerlo:

1.- En las funciones: “wspr_encode" y "wspr_message_prep”, modificar el de dato char array [ ] y pase a ser int array [ ] ( sin alterar el funcionamiento global de la función.)

A char is required to accept all values between 0 and 127 (included). So in common environments it occupies exactly one byte (8 bits). It is unspecified by the standard whether it is signed (-128 - 127) or unsigned (0 - 255).

An int is required to be at least a 16 bits signed word, and to accept all values between -32767 and 32767. That means that an int can accept all values from a char, be the latter signed or unsigned.

If you want to store only characters in a variable, you should declare it as char. Using an int would just waste memory, and could mislead a future reader.

Por lo que cuestiono este cambio, no seria mejor solo introducir los 3 caracteres en el apuntador y realizar la conversión de manera externa por una función, que permita, pasar de base-10 a base 36 (como un string) y viceversa?

2.- Crear una variable tipo de dato int y que sea insertado en las primeras 3 posiciones del apuntador call[] utilizando una conversión de valor a base-36 (donde 1K0 base 36 equivale a 2040 en base 10)

A char type can only accept a single character unless you declare an array of type char.

http://www.dreamincode.net/forums/topic/212654-convert-any-base36-to-base-ten/

Revisando este problema, aproveche para escribir una duda:

https://stackoverflow.com/questions/49092365/using-chars-into-an-int-datatype

La propuesta sería convertir el valor a base-36 después como string, e introducir valor por valor dentro de las primeras 3 posiciones del apuntador

Este es un boceto que escribieron en la primera respuesta para lograrlo pero tiene errores, los estoy revisando/corrigiendo

https://www.onlinegdb.com/rk-TDoK_f

#include <iostream>
#include <string.h>

int main(){
int base10Number=0;// = 2040;
char base36String[] = "2040";
int base36StringLenght = strlen(base36String);  

for(int i = 0; i < base36StringLenght ; ++i){
  char c = base36String[i];
  if(c <= '9'){
    c -= '0'; 
  }
  else{ 
    c = tolower(c) -  'a' + 10; 
  }
  base10Number *= 36;
  base10Number += c;
}
std::cout << base10Number << std::endl;
std::cout << base36String << std::endl;
std::cout << base36StringLenght << std::endl;   
}

https://stackoverflow.com/questions/49092365/using-chars-into-an-int-datatype

3.- El resto del apuntador debe poder contener cadenas strings ej: ‘A,B,C,D,E’ fijos, en las siguientes posiciones (4 y 5) del mismo arreglo call[].

Sobre esto requiero mas detalles, lo platicamos en la entrevista, pero el codigo original esta limitado a 5 posiciones en memoria y el ultimo valor debe ser un null, para poder realizar el CRC por el mismo código, asumo para adaptarse a las distintas versiones de arduino, por lo que siguiendo tu ejemplo, quedaria call[1K0A0], a menos que alteremos el tamaño del apuntador, sin embargo asumo ( aun no he verificado si esa limitación es por la memoria del uC, ver https://github.com/vazeri/WSPREncode/issues/7)

4.- Luego se debe hacer el proceso inverso, a partir del valor call=’1,K,0,A,B,C,D,E’ escribir en otra variable int numer2, el valor original 2040.

2040 en base-36 equivale a 93456 base-10 por lo que se confirma el correcto resultado del 1er programa, ( falta verificar de donde sale 1K0 )

Ver: https://www.wolframalpha.com/input/?i=2040_36

Para ir de vuelta

#include<string>
#include<algorithm>
#include <math.h>

string convert_base10_to_str_in_base(int64_t base10Number, uint8_t base) {
    string str="";
    str.reserve(log(base10Number ? base10Number : 1)/log(base)+1);
    bool neg=false;
    if(base10Number<0){
        base10Number=-base10Number;
        neg=true;
    }
    while(base10Number!=0){
        auto i = base10Number%base;
        if(i <= 9){
            str.push_back('0'+i); 
        }
        else{ 
            str.push_back(i - 10 +  'a'); 
        }
        base10Number /= base;
    }
    if(neg)
        str.push_back('-');
    reverse(str.begin(), str.end());
    return str;
}
jboggiano commented 6 years ago

Te adjunto el paper que explica el proceso del código.

El objetivo en definitiva es poder enviar un valor int (que va a ser tomado por un ADC) e insertarlo en la función whisper para transmisión y decodificarlo del lado del receptor.

Prestar atención a las funciones

wspr_code(char c) wspr_bit_packing( c ) convolve(c, s, 11, WSPR_BIT_COUNT) wspr_interleave(s) wspr_merge_sync_vector(s, symbols)

wspr_coding_process.pdf

wspr_coding_process.pdf

vazeri commented 6 years ago

saludos el pdf anexo no contiene ninguna anotacion

vazeri commented 6 years ago

pdf con anotaciones wspr_coding_process (4).pdf