Tablica char na tablicę int.

Odpowiedz Nowy wątek
2018-11-29 00:01
0

Dzień dobry,
wysyłam na mikrokontroler przez UART wartości z zakresu 0-4000. Każda cyfra zapisywana jest na mikrokontrolerze w odpowiednim buforze.

char buffor[buffor_size];

Następnie te wartości chciałabym przekazać na przetwornik mikrokontrolera, który przyjmuje jedynie wartości Uint32_t. Jednak nie potrafię przekonwertować tablicy charakterów na tablicę intów. Wiem, że zmienna char jest 8 bitowa, to oznaczało by, że musze wziąć po 4 symbole(cyfry) z bufora char, by otrzymać zmienną 32 bitową. Jednak nie potrafię w Internecie znaleźć odpowiednich funkcji.

Czyli tablica char wyglądałaby na przykład tak:

char buffor[12] = '4', '0', '0', '0', '0', '0', '0', '2', '0', '4' ,'5' , '7';

A tablica int:

int buffor1[3] = {4000, 2, 456};

W przykładach w Internecie znalazłam głównie przykłady z char *buffor. Dlatego nie pasowałyby do przesyłanych informacji. Z góry dziękuję.

edytowany 1x, ostatnio: furious programming, 2018-11-29 00:24

Pozostało 580 znaków

2018-11-29 00:06
kq
1

Oj nie, takich wartości by nie było w tej tablicy charów, aby otrzymać takie wartości intów.

Ogólnie od takich rzeczy jest memcpy, ale skoro piszesz na mikrokontrolery to może sie okazać, że masz słaby kompilator/bibliotekę standardową i trzeba będzie rozwiązać to w brzydki sposób.

W każdym razie, zakładając little-endian i 32-bitowy int:

char x[4] = { 0x01, 0x02, 0x03, 0x04 };
unsigned y;
memcpy(&y, x, sizeof(y));
assert(y == 0x04030201);

Jak widzisz podobieństwo widać w w wartościach heksadecymalnych; porównanie wartości dziesiętnych do wartości złożonych ze znaków nie ma sensu.


edytowany 1x, ostatnio: kq, 2018-11-29 00:07

Pozostało 580 znaków

2018-11-29 00:25
0

Tak wygląda mój buffor z wartościami przesłanymi na mikrokontroler.
Korzystam z STM32f303k8 i środowiska Keil v5.
Edytowałam załącznik: Jednak to przez błąd w transmisji, tak wygląda to poprawnie:

Capture.PNG

edytowany 3x, ostatnio: furious programming, 2018-11-29 01:31

Pozostało 580 znaków

2018-11-29 00:27
kq
0

No spoko, zobacz jak wyjdzie z użyciem memcpy. Nie znam tego środowiska - zwróć uwagę czy przypadkiem wygenerowany kod maszynowy nie będzie okropny.


Pozostało 580 znaków

2018-11-29 00:40
0

Gdy dochodzi do tej konwersji zmienne wyglądają jak w załączonych plikach.
W wejściowym 1 7 7 0 w y=3618609.

Jeszcze nadmienię, że tablica przyjmująca wartości nie będzie miała tylko 4 wartości, ale więcej, więc powinno się ją podzielić zawsze w równych odstępach po 4 symbole.

edytowany 2x, ostatnio: Cebulciax, 2018-11-29 00:44

Pozostało 580 znaków

2018-11-29 00:45
kq
1

Czekaj, źle Cię zrozumiałem chyba i namieszałem.

Czy ty przesyłasz to jako 12-znakowy tekst? Wtedy faktycznie pierwszy przykład masz poprawnie-ish, a zamiany dokonuj po prostu jako odpowiednie mnożenia.

int char_buf_to_int(static char buf[4])
{
    int result = 0;
    result += (buf[0] - '0') * 1000;
    result += (buf[1] - '0') *  100;
    result += (buf[2] - '0') *   10;
    result += (buf[3] - '0') *    1;
    return result;
}

// ...

char input[4] = { '1', '2', '3', '4' };
int val = char_buf_to_int(input);

Powyższe zakłada, że zawsze są 4 znaki i że nie ma sensu robić z tego pętli, a tak być nie musi.


edytowany 1x, ostatnio: kq, 2018-11-29 00:52

Pozostało 580 znaków

2018-11-29 00:55
0

To może od początku.
Z pliku WAVE pobieram wartości chwilowe amplitudy, które później wysyłam na mikrokontroler, nie są to stałe wartości. To dałam w pierwszym załączniku.
Następnie przesyłam je na mikrokontroler do tablicy char mającej 200 indeksów. Chciałabym podzielić tę tablice char tak by każdy int składał się z 4 indeksów tablicy char. Ponieważ przesyłając wartość 2000, zapisywana jest ona w 4 kolejnych indeksach.
buffor[0]='2';
buffor[1] = '0';
buffor[2] = '0';
buffor[3] = '0';
A w dalszych indeksach też zapisywane są wartości.
.
.
.
buffor[197] = '0';
buffor[198] = '1';
buffor[199]='1';
buffor[200]='2';
Co chciałabym by dało tablicę intów. tab[]={2000,...,112};

Jaki jest sens wysyłania wartości próbek w formie tekstowej? - _0x666_ 2018-11-29 11:06

Pozostało 580 znaków

2018-11-29 07:52

Skoro bufor ma mieć 200 char-ów, to aby przemielić cały potrzebujesz:

for (int cnt = 0; cnt < 200; cnt += 4)//tutaj pułapka - wielkość int zależy od maszyny, na 64bitowych ma rozmiar 8 bajtów.
{
    int converted = (charBuffer[cnt] - '0') * 1000
    converted += (charBuffer[cnt + 1] - '0') * 100;
    converted += (charBuffer[cnt + 2] - '0') * 10;
    converted += charBuffer[cnt + 3] - '0';
    //i teraz tego skonwertowanego inta wsadzasz sobie do tablicy intów    
}

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 3x, ostatnio: MasterBLB, 2018-11-29 08:59
To, czy int jest 64-bitowy, nie zależy tylko od platformy sprzętowej/systemowej, ale też od kompilatora. Jeśli się nie mylę, w VC++ i g++ int ma 32-bity pomimo kompilacji w 64-bitach. - _0x666_ 2018-11-29 11:01

Pozostało 580 znaków

2018-11-29 08:27
0
Cebulciax napisał(a):

Następnie przesyłam je na mikrokontroler do tablicy char mającej 200 indeksów. Chciałabym podzielić tę tablice char tak by każdy int składał się z 4 indeksów tablicy char. Ponieważ przesyłając wartość 2000, zapisywana jest ona w 4 kolejnych indeksach.

A w ilu indeksach jest zapisywana wartość 200? W jaki sposób?
Jeśli zapis pojedynczej liczby nie jest zawsze 4-cyfrowy to strona wysyłająca jest do przeróbki.


Szacuje się, że w Polsce brakuje 50 tys. programistów

Pozostało 580 znaków

2018-11-29 10:41
1
Cebulciax napisał(a):

To może od początku.
Z pliku WAVE pobieram wartości chwilowe amplitudy, które później wysyłam na mikrokontroler, nie są to stałe wartości. To dałam w pierwszym załączniku.
Następnie przesyłam je na mikrokontroler do tablicy char mającej 200 indeksów. Chciałabym podzielić tę tablice char tak by każdy int składał się z 4 indeksów tablicy char. Ponieważ przesyłając wartość 2000, zapisywana jest ona w 4 kolejnych indeksach.
buffor[0]='2';
buffor[1] = '0';
buffor[2] = '0';
buffor[3] = '0';
A w dalszych indeksach też zapisywane są wartości.
.
.
.
buffor[197] = '0';
buffor[198] = '1';
buffor[199]='1';
buffor[200]='2';
Co chciałabym by dało tablicę intów. tab[]={2000,...,112};

Jako, że nie wiadomo po co to robisz trudno zrozumieć o co chodzi, szczególnie, że opis wskazuje na jakieś bardzo dziwne zachowanie (nie brzmi ono znajomo i sensownie).
Możesz na chwilę zapomnieć jak chcesz to oprogramować i opisać funkcjonalność jaką ma wykonywać ten mikrokontroler?
Będzie łatwiej zrozumieć co zamierzasz i czy twoje zamiary są właściwe.
Np: "chcę mrugać diodami zależnie od natężenia dźwięku."

Czemu mnie niepokoi twój opis?

  • piszesz o dźwięku WAVE
  • grupujesz 4 znaki ASCII i chcesz zinterpretować je jako liczby dziesiętne co nijak się

Te dwie rzeczy zupełnie do siebie nie pasują i wskazują na to, że rozwiązanie jakiegoś problemu jest nieprawidłowe, albo opis niekompletny.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22, 2018-11-29 10:46

Pozostało 580 znaków

2018-11-29 15:07
0
MasterBLB napisał(a):

Skoro bufor ma mieć 200 char-ów, to aby przemielić cały potrzebujesz:

for (int cnt = 0; cnt < 200; cnt += 4)//tutaj pułapka - wielkość int zależy od maszyny, na 64bitowych ma rozmiar 8 bajtów.
{
    int converted = (charBuffer[cnt] - '0') * 1000
    converted += (charBuffer[cnt + 1] - '0') * 100;
    converted += (charBuffer[cnt + 2] - '0') * 10;
    converted += charBuffer[cnt + 3] - '0';
    //i teraz tego skonwertowanego inta wsadzasz sobie do tablicy intów    
}

Dziękuję, właśnie o takie coś chodziło.

Jeśli chodzi o przyczynę takiego pytania to śpieszę z odpowiedzią.
Chcę zrobić wzmacniacz audio, który będzie komunikował się z komputerem przez Bluetooth, jako, że przez UART można przesłać tylko 8-bit char, a do przetwornika cyfrowo-analogowego 32bit uint, po przesłaniu musze zrobić konwersję jednego z typów na drugi. Chciałam pominąć, przez moją małą wiedzę z zakresu programowania, odczytywanie wartości pliku WAVE. Dlatego najpierw konwertuję go na komputerze na chwilowe wartości amplitudy, a następnie wysyłam te wartości na mikrokontroler. Może niezbyt elegancka praktyka, ale z moja wiedzą, jedyna możliwa do zrealizowana.
Dziękuję wszystkim za odpowiedzi.

Liczba 200 zapisywana jest w sposób '0', '2' ,'0','0'. Więc zawsze z 4 elementów char, chciałam robić jedną wartość int.

edytowany 1x, ostatnio: Cebulciax, 2018-11-29 15:08
To pyknij ptaszka pod postem. - MasterBLB 2018-11-29 15:09
To nie tłumaczy, dlaczego wysyłasz próbki w formie tekstowej. To totalnie nie efektywne. 16-bitowe próbki możesz przecież zapakować do bufora int16_t[] i wysłać jako ciąg bajtów. - _0x666_ 2018-11-30 10:10
Przez program LabView, z tego co się orientuję można wysyłać jedynie stringi. - Cebulciax 2018-12-02 19:45

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0