collapse

* Posts Recentes

Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]


Focos LED SMD por almamater
[16 de Dezembro de 2023, 14:12]


I Belive por dropes
[15 de Dezembro de 2023, 13:59]


Carga de corrente eletrónica ZPB30A1 60W por jm_araujo
[11 de Dezembro de 2023, 13:27]

Autor Tópico: Random number  (Lida 2503 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline almamater

  • Mini Robot
  • *
  • Mensagens: 1.914
    • GrcByte - Projectos
Random number
« em: 28 de Novembro de 2020, 00:12 »
Alguém que tem alguma forma de gerar números aleatórios mas mesmo aleatórios?
Não precisava de algo muito mega eficiente mas é que a forma 'normal' que existe no Arduino para Random Generator não é lá muito aleatório.

Andei a pesquisar e há N discussões sobre isto e cheguei a esta biblioteca: Entropy library, que até acho que funciona muito bem mas ao mesmo tempo é algo muito elaborado parece-me para o que quero..

Simplesmente entre os números X e Y quero obter um número mas que não se esteja sempre a repetir que nem parece aleatório.

Com o método 'normal' do randomSeed(analogRead(0)) há forma de melhorar o resultado? Provocar mais ruído no pino usado?

Offline KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.480
Re: Random number
« Responder #1 em: 28 de Novembro de 2020, 01:20 »
Citar
Alguém que tem alguma forma de gerar números aleatórios mas mesmo aleatórios?
Citar
a forma 'normal' que existe no Arduino para Random Generator não é lá muito aleatório.

Em que te baseias que nao e' suficientemente aleatorio para ti?

Sera um pseudo random generator, que deverá ter uma repetição do padrão. Qual é essa frequencia dessa repetição?

Depois de saberes, podes procurar outros altoritmos pseudo-aleatorios e escolher um que tenha uma repeticao mais longa.

Os MCUs mais recentes trazem um módulo analógico para gerar entropia / valores aleatorios..
de resto, por software, só é possivel pseudo-aleatoriedade.


Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Random number
« Responder #2 em: 28 de Novembro de 2020, 13:43 »
Fizeste-me lembrar a "plotter" que levei à makerfaire em 2014. Tem um botão que dá inicio ao desenho de um perfil de cidade. Cada perfil é gerado com elementos aleatórios e é único (bom, na verdade é um dos 65536 perfis possíveis :D). Para obter essa aleatoriedade e ligá-la à pessoa que carrega no botão, tenho um contador (16 bits) que incrementa constantemente em wraparound à "velocidade do CPU" e pára quando a pessoa carrega no botão. Depois uso o valor desse contador como semente para o gerador de números aleatórios. Isto corre num ATTiny46. Não sei quão bom é o gerador de números aleatórios mas cá fica na mesma; pelo código que tenho comentado no projecto, foi uma preocupação minha e fiz um teste para ver o aspecto da coisa. Acho que na altura pesquisei e encontrei esse algoritmo em algum lado. Seguem-se excertos do código.

typedef  uint16_t  word;
typedef  uint8_t  byte;

static word  gRand = 89;

static byte rand (void)
{
    static const byte  EEMEM sSeeds[8] = {5, 23, 51, 89, 43, 11, 7, 7};
    static byte  sIdx = 5;

    sIdx = (sIdx + gRand + 3) & 0x07;
    gRand = gRand * 109 + eeprom_read_byte((byte*)(&sSeeds + sIdx));
    return gRand & 0xff;
}

// Pick a random number from 0 to (n-1) (one number from a set of n).
static byte Rand (byte n)
{
    return ((word)n) * rand() / 255;
}

(...)

static void WaitKey (void)
{
    word  ctr = gRand;
    while (PINB & _BV(ePinDRLL))  ctr++;
    gRand = ctr;
}

// main() ...
    /*/ Quick check of the randomness of our rand function
    {
        byte  a;
        for (a = 0; a < 100; a++)
        {
            sendch(Rand(2) + '0');      // 0 or 1
            USendEEStr("\r\n");
        }
        USendEEStr("--\r\n");
        for (a = 0; a < 100; a++)
        {
            sendch(Rand(10) + '0');     // 0 to 9
            USendEEStr("\r\n");
        }
    }*/


« Última modificação: 28 de Novembro de 2020, 13:47 por Njay »

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 2.185
Re: Random number
« Responder #3 em: 28 de Novembro de 2020, 14:23 »
Existem várias formas de se gerar números aleatórios:
- Pseudo aleatório (funciona bem quando vai buscar o timer do micro ou de um rtc)
- Intervenção humana (vai buscar um nº do incrementador ao ser pressionado um botão)

Este último é 100% aleatório e coloquei esse processo quando desenvolvi o jogo "simon" ou "tetris"
Parece que o Njay também usou um parecido  ::)

Em programação no pc, para se gerar um nº executa-se randomize, que vai registar o inicio dos nºs de acordo com o timer, ao se chamar o comando random, este será uma série em pseudo (através de um calculo interno).
« Última modificação: 28 de Novembro de 2020, 14:41 por dropes »

Offline almamater

  • Mini Robot
  • *
  • Mensagens: 1.914
    • GrcByte - Projectos
Re: Random number
« Responder #4 em: 28 de Novembro de 2020, 17:50 »
 :)

Quando digo que a função que referi não é 'suficientemente aleatoria' é porque, para além de existirem mais pessoas a dizer o mesmo, implementei a mesma há uns anos num Attiny para que sejam gerados nºs aleatórios até 30 (se não me falha a memória) e por forma a que seja depois escolhido o ficheiro MP3 correspondente.. acontece que há músicas que estão constantemente a tocar e outras não, mesmo sendo aleatório parece que há um padrão e os mesmos números acabam sempre por sair.

Logicamente não tenho nada muito em concreto para defender esta minha teoria, a não ser o que li sobre isto e de facto na prática com o 'projecto' que fiz há uns anos e que ainfa hoje tem o mesmo comportamento :)

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Random number
« Responder #5 em: 28 de Novembro de 2020, 18:54 »
Ahh, mas se a aplicação é essa, o que tu queres fazer é arranjar uma playlist "baralhada". Aí tens a garantia que todas as músicas vão ser tocadas durante uma passagem pela playlist. Copias a playlist ou a lista de músicas para uma lista à parte, a lista "aleatória". Mas em vez de percorreres a lista inicial de uma ponta à outra, escolhes um elemento ao calhas e copia-lo para a lista random. Depois tiras esse elemento da lista original, ficando apenas os elementos que ainda não foram escolhidos. E continuas a fazer isso até que ficas com a lista original vazia. No final tens uma lista random em que todas as músicas são tocadas exactamente uma vez. Tás a ver o algoritmo?

Há outras formas de fazer, mas o essencial é que ficas com uma lista que tem à mesma todas as músicas mas por uma ordem aleatória.
« Última modificação: 28 de Novembro de 2020, 18:58 por Njay »

Offline almamater

  • Mini Robot
  • *
  • Mensagens: 1.914
    • GrcByte - Projectos
Re: Random number
« Responder #6 em: 28 de Novembro de 2020, 19:07 »
:) estou a ver e é uma boa solução sim :) porque é exatamente esse o meu problema, nem todas as músicas são tocadas da forma como implementei o código, não quer dizer que um dia não sejam escolhidas mas é mais difícil.

Offline KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.480
Re: Random number
« Responder #7 em: 30 de Novembro de 2020, 00:30 »
Uma sugestão talvez ainda mais fácil, é copiar a lista e fazer trocas (swap) aleatorias dos elementos. O numero de trocas e a posição dos elementos a trocar é aleatória.
Baralhar a lista :)

Neste caso a lista, os elementos são os indices relativos à lista original.

Offline dio123

  • Mini Robot
  • *
  • Mensagens: 1.032
Re: Random number
« Responder #8 em: 30 de Novembro de 2020, 06:41 »
Nas questões das musicas até o meu radio, em modo mix de escolher musicas aleatórias consegue nao tocar as musicas todas, e ainda consegue repetir algumas..
Se calhar fazer random, não tem de ser tão random. Por exemplo quando calhar número que ja tenha saido faz random a lista que nunca tenha saido.