random() Function isn't random at all I'm using the random() to generate random coordinates for coins in a simple game console. The problem here is that the random() function is not generating random numbers, since the coin is at the same coordinates every single time I upload it. I am using the Adafruit GFX library with the Adafruit 1.44&quot; Color TFT LCD Display. Here is my code (sorry, it's kind of long).
//necessary libraries
#include &lt;Adafruit_GFX.h&gt;    // Core graphics library
#include &lt;Adafruit_ST7735.h&gt; // Hardware-specific library
#include &lt;SPI.h&gt;

//colors
#define BLACK    0x0000
#define BLUE     0x001F
#define RED      0xF800
#define GREEN    0x07E0
#define CYAN     0x07FF
#define MAGENTA  0xF81F
#define YELLOW   0xFFE0 
#define WHITE    0xFFFF

//pins
#define TFT_CS  10
#define TFT_RST  9
#define TFT_DC   8

//joystick variables
const int VRxPin = A1;
const int VRyPin = A0;
const int SWPin  = 7;
bool mov = false;

//data read from joystick pins
int x = 0;
int y = 0;
int SW = 0;

// X and Y coords for entities
int playerx = 50;
int playery = 50;

long coinx;
long coiny;

//game variables
int score = 0;

//defining the tft class
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

//useful text function
void output(char *text, int x, int y, uint16_t color, bool wrap = 0){
  tft.setCursor(x, y);
  tft.setTextColor(color);
  tft.setTextWrap(wrap);
  tft.print(text);
}

//there is probably a better way to do this but im too lazy to find it
void num_output(int text, int x, int y, uint16_t color, bool wrap = 0){
  tft.setCursor(x, y);
  tft.setTextColor(color);
  tft.setTextWrap(wrap);
  tft.print(text);
}

//clears screen
void clear() {
  tft.fillScreen(BLACK);
}

//setup (lcd init &amp; startup screen)
void setup() {
  Serial.begin(9600);
  pinMode(SWPin,INPUT_PULLUP);
  tft.initR(INITR_GREENTAB);
  
  long coinx = random(20, 100);
  long coiny = random(20, 100);
  
  clear();
  output(&quot;RAMBUTAN&quot;, 40, 60, RED);
  delay(1000);
  clear();
  tft.fillRect(playerx, playery, 5, 5, WHITE);
  tft.fillCircle(coinx, coiny, 5, YELLOW);
}

void loop() {
  //reads data from joystick pins every single tick
  int VRx = analogRead(VRxPin);
  int VRy = analogRead(VRyPin);
  int SW = digitalRead(SWPin);
  
  //converts joystick pin data into directions
  if (VRx &gt; 250 &amp;&amp; VRx &lt; 750 &amp;&amp; VRy &gt; 250 &amp;&amp; VRy &lt; 750) {
    // middle
  } else if (VRx &gt; 511.5 &amp;&amp; VRy &lt; 750 &amp;&amp; VRy &gt; 240) {
    // right
    playery -= 5;
    mov = true;
  } else if (VRx &lt; 511.5 &amp;&amp; VRy &lt; 750 &amp;&amp; VRy &gt; 240) {
    // left
    playery += 5;
    mov = true;
  } else if (VRy &gt; 511.5 &amp;&amp; VRx &lt; 750 &amp;&amp; VRx &gt; 240) {
    // up
    playerx += 5;
    mov = true;
  } else if (VRy &lt; 511.5 &amp;&amp; VRx &lt; 750 &amp;&amp; VRx &gt; 240) {
    // down
    playerx -= 5;
    mov = true;
  } else {
    mov = false;
  }

  if (mov == true) {
    clear();
    tft.fillRect(playerx, playery, 5, 5, WHITE);
    num_output(score, 10, 10, WHITE);
    tft.fillCircle(coinx, coiny, 5, YELLOW);
    mov = false;
  }
  delay(100);
}
You are correct, random() isn't random - it's pseudo random. It returns successive results from a mathematical formula which, to all intents and purposes, is random. It's also predictable, as you have seen.
The formula has a starting value, called the seed, which you can choose your self. Changing that seed gives you a different sequence of random-like numbers.
So the trick is to set the seed to something that is truly random. One common source of randomness, or entropy, is an unconnected ADC input:
randomSeed(analogRead(A3));

You can read more about the randomSeed() function here.