You need to dynamically account for both speed and creation of the obstacle.
max_loops = int(16 / obstacle_manager.obstacle_speed)
if max_loops < 1:
max_loops = 1
if loops >= max_loops:
obstacle_manager.create_obstacle()
scoreboard.score_up()
loops = 0
obstacle_manager.move_obstacles()