Implementing Infrared sensor to an arduino - arduino

Is there a way to implement an Infrared sensor as input in an Arduino code ? I want the sensor to send data to the Arduino in values (changes of the IR position) and then use that value as an input in the software.
Code is an example of a light resistive sensor that turns on the LED every time it's dark, and turns it off when the light sensor detects its bright.
int sensor1Value = 0;
void setup()
{
// declare the ledPins as an OUTPUT:
pinMode(13, OUTPUT);
}
void loop() {
// read the value from the sensor:
sensor1Value = analogRead(A0);
{
if(sensor1Value <200) // check the value of sensor
{ //if the value is less than 200 then turn the leds on
digitalWrite(13, HIGH);
delay(500);
}
else // if the value is greater than or equal to 200 then turn leds off
{
digitalWrite(13, LOW);
delay(500);
}
}

The simpliest way is to use IR phototransistor
There is no need for a delay after each digitalWrite(), just add it at the end of the loop() function.
void loop() {
// read the value from the sensor:
sensor1Value = analogRead(A0);
if(sensor1Value <200) // check the value of sensor
{ //if the value is less than 200 then turn the leds on
digitalWrite(13, HIGH);
}
else // if the value is greater than or equal to 200 then turn leds off
{
digitalWrite(13, LOW);
}
delay(500);
}

Related

How to use millis on traffic light controller in Arduino

I'm doing a smart city project with my Arduino and I have a question. I have created 2 functions and one of them is the traffic light controller and I use the delay() to make them have the right delays between them. But I have a problem. I call both of the functions inside loop(), but one of them only runs when the other is finished. Is there any way to run them both? I've seen people using millis().
My code:
int smartled1 = 13;
int smartled2 = 12;
int smartled3 = 11;
int smartled4 = 10;
int smartled5 = 9;
int smartled6 = 8;
int smartled7 = 7;
int smartled8 = 6;
int smartled9 = 50;
int smartled10 = 51;
int smartled11 = 52;
int smartled12 = 53;// Pin para ligar o led
int sensorPin = A0; // Seleção do pin de entrada do LDR
int sensorValor = 0; // Variavel de armazenamento do LDR inicializada a 0
int semaforo1[]= {22, 24, 26};
int semaforo2[]= {5, 4, 3};
int semaforo3[]= {29, 31, 33};
int semaforo4[]= {28, 30, 32};
int Delayvermelho = 5000;
int Delayamarelo = 2000;
void setup() {
Serial.begin(9600); // Define a porta serie para comunicação
pinMode(smartled1, OUTPUT);
pinMode(smartled2, OUTPUT);
pinMode(smartled3, OUTPUT);
pinMode(smartled4, OUTPUT);
pinMode(smartled5, OUTPUT);
pinMode(smartled6, OUTPUT);
pinMode(smartled7, OUTPUT);
pinMode(smartled8, OUTPUT);
pinMode(smartled9, OUTPUT);
pinMode(smartled10, OUTPUT);
pinMode(smartled11, OUTPUT);
pinMode(smartled12, OUTPUT);// Define o pin do Led como saída
for (int i = 0; i < 3; i++) {
pinMode(semaforo1[i], OUTPUT);
pinMode(semaforo2[i], OUTPUT);
pinMode(semaforo3[i], OUTPUT);
pinMode(semaforo4[i], OUTPUT);
}
}
void loop() {
smart_lights();
semaforos_cruzamento();
}
void semaforos_cruzamento(){
// Making Green LED at signal 1 and red LED's at other signal HIGH
digitalWrite(semaforo1[2], HIGH);
digitalWrite(semaforo1[0], LOW);
digitalWrite(semaforo2[0], HIGH);
digitalWrite(semaforo3[0], HIGH);
digitalWrite(semaforo4[0], HIGH);
delay(Delayvermelho);
// Making Green LED at signal 1 LOW and making yellow LED at signal 1 HIGH for 2 seconds
digitalWrite(semaforo1[1], HIGH);
digitalWrite(semaforo1[2], LOW);
delay(Delayamarelo);
digitalWrite(semaforo1[1], LOW);
// Making Green LED at signal 2 and red LED's at other signal HIGH
digitalWrite(semaforo1[0], HIGH);
digitalWrite(semaforo2[2], HIGH);
digitalWrite(semaforo2[0], LOW);
digitalWrite(semaforo3[0], HIGH);
digitalWrite(semaforo4[0], HIGH);
delay(Delayvermelho);
// Making Green LED at signal 2 LOW and making yellow LED at signal 2 HIGH for 2 seconds
digitalWrite(semaforo2[1], HIGH);
digitalWrite(semaforo2[2], LOW);
delay(Delayamarelo);
digitalWrite(semaforo2[1], LOW);
// Making Green LED at signal 3 and red LED's at other signal HIGH
digitalWrite(semaforo1[0], HIGH);
digitalWrite(semaforo2[0], HIGH);
digitalWrite(semaforo3[2], HIGH);
digitalWrite(semaforo3[0], LOW);
digitalWrite(semaforo4[0], HIGH);
delay(Delayvermelho);
// Making Green LED at signal 3 LOW and making yellow LED at signal 3 HIGH for 2 seconds
digitalWrite(semaforo3[1], HIGH);
digitalWrite(semaforo3[2], LOW);
delay(Delayamarelo);
digitalWrite(semaforo3[1], LOW);
// Making Green LED at signal 4 and red LED's at other signal HIGH
digitalWrite(semaforo1[0], HIGH);
digitalWrite(semaforo2[0], HIGH);
digitalWrite(semaforo3[0], HIGH);
digitalWrite(semaforo4[2], HIGH);
digitalWrite(semaforo4[0], LOW);
delay(Delayvermelho);
// Making Green LED at signal 4 LOW and making yellow LED at signal 4 HIGH for 2 seconds
digitalWrite(semaforo4[1], HIGH);
digitalWrite(semaforo4[2], LOW);
delay(Delayamarelo);
digitalWrite(semaforo4[1], LOW);
}
void smart_lights(){
int sensorValor = analogRead(sensorPin);// Lê o valor fornecido pelo LDR
Serial.println(sensorValor);//Imprime os valores provenientes do sensor na ecrã
// Caso o valor lido na porta analógica A5 seja maior do que
// 800, acende o LED
// Ajuste o valor abaixo de acordo com o circuito
if (sensorValor < 400)
{
digitalWrite(smartled1, HIGH);
digitalWrite(smartled2, HIGH);
digitalWrite(smartled3, HIGH);
digitalWrite(smartled4, HIGH);
digitalWrite(smartled5, HIGH);
digitalWrite(smartled6, HIGH);
digitalWrite(smartled7, HIGH);
digitalWrite(smartled8, HIGH);
digitalWrite(smartled9, HIGH);
digitalWrite(smartled10, HIGH);
digitalWrite(smartled11, HIGH);
digitalWrite(smartled12, HIGH);
}
else //Caso contrário, apaga o led
{
digitalWrite(smartled1, LOW);
digitalWrite(smartled2, LOW);
digitalWrite(smartled3, LOW);
digitalWrite(smartled4, LOW);
digitalWrite(smartled5, LOW);
digitalWrite(smartled6, LOW);
digitalWrite(smartled7, LOW);
digitalWrite(smartled8, LOW);
digitalWrite(smartled9, LOW);
digitalWrite(smartled10, LOW);
digitalWrite(smartled11, LOW);
digitalWrite(smartled12, LOW);
}
}
Yes, you can use state machines.
Example:
// totally randon delays. Prime to each other.
static const unsigned char MY_EVENT_TIMEOUT = 100; // in milliseconds.
static const unsigned int HIS_EVENT_TIMEOUT = 2533; // in milliseconds.
// setup two sta=te machines. In this example both state machines will simply
// wait a bit before toggling between two states.
// state machines consist of different state values, a state variable, and some data
enum MyEventState {
my_event_state_initial, // we'll just start timing
my_event_state_1,
my_event_state_2,
/* and so on... */
};
MyEventState my_state = my_state_initial;
unsigned char my_event_timestamp; // largest my_event delay is less than 255 ms
// second state machine.
enum HisEventState {
his_event_state_iinitial, // we'll wait for some external event
his_event_state_1,
his_event_state_2,
/* more states if you need */
};
HisEventState his_state = his_state_initial;
unsigned int his_event_timestamp; // largest his_event delay is less than 65535 ms
void my_event_handler()
{
switch (my_state)
{
case my_event_state_initial:
// initialize our timestamp and go straight to state 1
my_event_timestamp = (unsigned char)millis();
my_state = my_event_state_1;
// passing though to execute next state handler immediately
case my_event_state_1:
// in real application, you'd likely CHECK for a triggering event first
// and check millis() for timeouts, etc. Using different states to
// check for time out... Note the use of subtraction of UNSIGNED
// values to avoid rollover issues altogether
// the extra cast is the correct way to to it. C++ subtraction MAY
// return an unsigned int, according to the standard. In practice, it
// does not happens for 8 and 16-bit MCUs.
// no matter what you do, do not wait, poll your input line, or
// check if there are bytes on the serial buffer, do not block.
if ((unsigned char)((unsigned char)millis() - my_event_timestamp) < MY_EVENT_TIMEOUT)
{
// not enough time has elapsed, nothing to do, so return
return;
}
my_event_timestamp = (unsigned char)millis(); // get a time stamp
my_state = my_event_state_2; // change state
// passing though to execute next state handler immediately
case my_event_state_2:
// it's always the same logic in this simple state machine,
// but you can put any logic you want here to turn one light on or off,
// check inputs, etc..
if ((unsigned char)millis() - my_event_timestamp < MY_EVENT_TIMEOUT)
{
// not enough time has elapsed, nothing to do, so return
return;
}
my_event_timestamp = (unsigned char)millis(); // get a time stamp
my_state = my_event_state_1; // change state
// we're done. the handler for state 1 will execute the next time
// loop() is called.
// This would be the place you could find an infamous goto within a
// switch blck, if timing needs to be suoer duper extra tight.
// It does happen sometimes, but rarely.
return;
}
}
void his_event_handler()
{
// this is the same logic, but with a different beat.
// since these handlers do not block for timers or events
// the handlers appear to run 'concurrently'
switch (his_state)
{
case his_event_state_initial:
// initialize our timestamp and go straight to state 1
his_event_timestamp = (unsigned int)millis();
his_state = his_event_state_1;
// passing though to execute next state handler immediately
case his_event_state_1:
if ((unsigned int)millis() - his_event_timestamp < HIS_EVENT_TIMEOUT)
{
// not enough time has elapsed, nothing to do, so return
return;
}
his_event_timestamp = (unsigned int)millis(); // get a time stamp
his_state = his_event_state_2; // change state
// passing though to execute next state handler immediately
case his_event_state_2:
if ((unsigned int)millis() - his_event_timestamp < HIS_EVENT_TIMEOUT)
{
// not enough time has elapsed, nothing to do, so return
return;
}
his_event_timestamp = (unsigned int)millis(); // get a time stamp
his_state = his_event_state_1; // change state
// we're done. the handler for state 1 will execute the next time
// loop() is called.
return;
}
}
void setup()
{
}
void loop() {
// call our concurrent state machines
my_event_handler();
his_event_handler();
/* some other non-blocking code... */
}

Ultrasonic sensors

Now i am using 2 ultrasonic sensors but i found that they become unstable outdoors and give random readings .....although they act normally inside a room .....how can i solve this problem???
That is the code
it seems like the off Sensor always Reading and i checked the wiring and it is good so i don't really know where is the problem is ??
#define trig 2
#define echo 3
#define led 7
#define relay 4
#define trig2 10
#define echo2 9
#define led2 8
long duration,distance,OnSensor,OffSensor;
void setup() {
// put your setup code here, to run once:
pinMode(echo,INPUT);
pinMode(echo2,INPUT);
Serial.begin(9600);
pinMode(led,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(relay,OUTPUT);
pinMode(trig,OUTPUT);
pinMode(trig2,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(led,LOW);
digitalWrite(led2,LOW);
digitalWrite(relay,LOW);
SonarSensor(trig2, echo2);
OffSensor = distance;
delay(50);
SonarSensor(trig, echo);
OnSensor=distance;
if(OnSensor<80&&OffSensor>=80){//sensor 1 activated
digitalWrite(led,HIGH);
digitalWrite(relay,HIGH);
delay(150);
digitalWrite(led,LOW);
digitalWrite(relay,LOW);
delay(1000);
digitalWrite(led,HIGH);
digitalWrite(relay,HIGH);
delay(150);
digitalWrite(led,LOW);
digitalWrite(relay,LOW);
}
else if(OnSensor>80&&OffSensor>80){//No sensor activated
digitalWrite(led,LOW);
digitalWrite(relay,LOW);
}
else if(OnSensor>80&&OffSensor<80){//sensor2 activated
digitalWrite(led2,HIGH);
digitalWrite(relay,LOW);
delay(5000);
}
else if(OnSensor<80&&OffSensor<80){//Both sensors activated
digitalWrite(led2,HIGH);
digitalWrite(led,HIGH);
digitalWrite(relay,LOW);
delay(3000);
}
}
void SonarSensor(int trigPin,int echoPin)
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration*0.034/2;
}
I think there are 2 problem here
You use 2 sensor
List item
Use use it outdoor
From my experience the ultra sonic wave can bouncing around object many time. depend on your setup, second sensor might read echo form first sensor.
follow these step
1. Try to use 1 sensor per time to see if it error
2. If single sensor work you should add more delay after sensor reading
3. Plot the data to see how it look like you might need digital filter to improve reading
For step 3 if you use sensor as On Off by threshold you can see my example code.
This code work the same way as button de-bouncing so in need to trig continuously for 10 time to prevent false alarm (This code for single sensor)
#define ULTRASONIC_TRIG_PIN 8
#define ULTRASONIC_ECHO_PIN 7
#define RELAY_PIN 4
/**/
#define ULTRASONIC_INTERVAL_MS 100//50
#define ULTRASONIC_TRIG_COUNT_THRESH 10
#define ULTRASONIC_DISTACE_THRESH_CM 50
/**/
#define RELAY_TRIG__INTERVAL_MS 5000
#define RELAY_TRIG_LOGIC HIGH
void setup()
{
pinMode (RELAY_PIN, OUTPUT);
pinMode (ULTRASONIC_TRIG_PIN, OUTPUT);
pinMode (ULTRASONIC_ECHO_PIN, INPUT);
Serial.begin(115200);
}
void loop()
{
static unsigned long ultrasonic_timer = millis();
static unsigned long relay_trig_timer = millis();
static float us_distance_cm = 0;
static int us_trig_count = 0;
static byte relay_state = !RELAY_TRIG_LOGIC; // initial value as off;
if (millis() - ultrasonic_timer >= ULTRASONIC_INTERVAL_MS) {
ultrasonic_timer += ULTRASONIC_INTERVAL_MS;
us_distance_cm = getDistanceCM();
if (us_distance_cm <= ULTRASONIC_DISTACE_THRESH_CM) {
if (us_trig_count >= ULTRASONIC_TRIG_COUNT_THRESH) {
digitalWrite(RELAY_PIN, RELAY_TRIG_LOGIC);
relay_state = RELAY_TRIG_LOGIC;
relay_trig_timer = millis();
}
else {
us_trig_count++;
}
}
else {
us_trig_count = 0;
}
Serial.print("distance = ");
Serial.print(us_distance_cm);
Serial.print("cm, relay = ");
Serial.print(relay_state);
Serial.print(", count = ");
Serial.println(us_trig_count);
}
if (relay_state == RELAY_TRIG_LOGIC) {
if (millis() - relay_trig_timer > RELAY_TRIG__INTERVAL_MS) {
relay_state = !RELAY_TRIG_LOGIC;
digitalWrite(RELAY_PIN, !RELAY_TRIG_LOGIC);
}
}
}
float getDistanceCM() {
digitalWrite(ULTRASONIC_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(ULTRASONIC_TRIG_PIN, LOW);
unsigned long duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH, 50000);
float distance = float(duration * 343) / 20000.0;
delay(5);
return distance;
}

Pin mode is always LOW when it should be HIGH

I'm working with simple Arduino where I'm trying to turn on a LED light by using serial print and turning off the LED Light when I click the button or use the switch on the board, when the pin is in the ground.
At the moment, I can turn on the led light by serial, however when I click the button the LED light will switch off but then never switch on, and that's happening because the state is being stuck at low all the time and never switching back to high.
Here's the code:
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 3; // the number of the LED pin
int state = 0;
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
if (Serial.available())
{
state = Serial.parseInt();
if (state == 1)
{
digitalWrite(ledPin, HIGH);
Serial.println("ON");
}
}
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == LOW) {
state = 0;
// turn LED OFF:
Serial.println("off");
digitalWrite(ledPin, LOW);
}
// IMP : This Never runs. the state is always off therefore when i send to serial " 1" the led just blinks
else {
Serial.println("off");
}
}
The state is always off therefore when I send to serial " 1" the LED just blinks
I think you are reading state from PIN using wrong function.
if (Serial.available())
{
state = Serial.parseInt();
Why not use https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/ ?
Are you sure this condition is evaluated to true? if (Serial.available()) ?
You are making the logic too much complicate. Just check the serial if it is available and have the desire value turn led on else check the button and if it pressed turn the led off. On other conditions DO NOTHING. That is all you need.
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 3; // the number of the LED pin
int state = 0;
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup()
{
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop()
{
if (Serial.available())
{
state = Serial.parseInt();
if (state == 1)
{
digitalWrite(ledPin, HIGH);
Serial.println("ON");
}
}
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
else if (digitalRead(buttonPin) == HIGH)
{
// turn LED OFF:
Serial.println("off");
digitalWrite(ledPin, LOW);
}
}

Arduino Code LED failure to alternate

Traffic light just stays on red rather than alternating.
Wanted it to stay on for 10s then off for 10s, continuing ad infinitum.
Dont want to use the delay function cos need to do other stuff while the LED continues to alternate.
Thanks
int red = 10; // red traffic light LED on pin 10
int redcounter;
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(red, OUTPUT);
digitalWrite(red, LOW);
redcounter = 0;
}
// the loop routine runs over and over again forever:
void loop()
{
redcounter = redcounter +1;
if(redcounter==1000)
{
redcounter=0;
if(digitalRead(red)==HIGH)
{
digitalWrite(red, LOW);
}
if(digitalRead(red)==LOW)
{
digitalWrite(red, HIGH);
}
}
You try to read a port which is configured as an OUTPUT. I don't know if this is supposed to work, but it would be more clear if you simply use another port as INPUT and feedback the signal you want to check in that port. I'm not sure however if it makes much sense to check the state of a signal you generate yourself (?). Moreover your redcounter is just "Active waiting", and arduino provides a delay function which does exactly that.
int red=10;
int signal=11;
void setup()
{
pinMode(red, OUTPUT);
pinMode(signal, INPUT);
digitalWrite(red, LOW);
}
void loop()
{
delay(1000);
if(digitalRead(signal)==HIGH)
{
digitalWrite(red, LOW);
}
if(digitalRead(signal)==LOW)
{
digitalWrite(red, HIGH);
}
}
Use elseif instead of if here:
if(digitalRead(red)==HIGH)
{
digitalWrite(red, LOW);
}
else if(digitalRead(red)==LOW)
{
digitalWrite(red, HIGH);
}
In your old solution every time red turned low, it was turned high a moment later.
Two issues in your code are that digitalread will not read an output pin and if you use an increment counter you won't be able to accurately denote time. Sorry if I missed a bracket or something I was doing this on the mobile app.
Use this:
int red = 10; // red traffic light LED on pin 10
int redcounter;
boolean pinState = false;
int delayTime = 10000;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(red, OUTPUT);
digitalWrite(red, LOW);
redcounter = millis();
}
// the loop routine runs over and over again forever:
void loop() {
if((millis() - red counter) > delayTime) {
redcounter=millis();
if(pinState) {
digitalWrite(red, LOW);
pinState = false;
}
else {
digitalWrite(red, HIGH);
pinState = true;
}
}
}

Receiving SMS using GSM and controlling LED using Arduino

Has someone come up with a solution with the above stated problem?
We are using Arduino Duemilanove and SIM 900 GSM module (http://robokits.co.in/shop/index.php?main_page=product_info&products_id=303)
We've tried to work on the similar problem of lightning LEDs from port 9-12 when we send an sms #aibicidi, where i = 0 or 1, 0 =off, 1=on. E.g. #a1b1c1d1 will switch on all the LEDs.
When we upload the code and run it through serial monitor and enter the #a1b1c1d1 in the serial monitor, we can see all the LEDs lighten up. But if we send the sms with having content "#a1b1c1d1", we don't see any function of LEDs.
It would be great if anyone can give some guidance about the same.
char inchar; //Will hold the incoming character from the Serial Port.
int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;
void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
//Initialize GSM module serial port for communication.
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Serial.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}
void loop()
{
//If #a1b1c1d1 comes as sms, all LEDs should light up.
if(Serial.available() >0)
{
inchar=Serial.read();
if (inchar=='#')
{
delay(10);
inchar=Serial.read();
//first led
if (inchar=='a')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led1, LOW);
}
else if (inchar=='1')
{
digitalWrite(led1, HIGH);
}
delay(10);
//Second led
inchar=Serial.read();
if (inchar=='b')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led2, LOW);
}
else if (inchar=='1')
{
digitalWrite(led2, HIGH);
}
delay(10);
// Third led
inchar=Serial.read();
if (inchar=='c')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led3, LOW);
}
else if (inchar=='1')
{
digitalWrite(led3, HIGH);
}
delay(10);
//Fourth led
inchar=Serial.read();
if (inchar=='d')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led4, LOW);
}
else if (inchar=='1')
{
digitalWrite(led4, HIGH);
}
delay(10);
}
}
Serial.println("AT+CMGD=1,4"); // delete all SMS
}
}
}
}
}
First do not use delay
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
This is neither necessary nor reliable. Instead of waiting some random time, you can check the network status with AT+CFUN and/or AT+COPS. If the GSM module is already attached to a network when you open the serial connection, it is a waste of time waiting like that. And if is not attached you should wait explicitly for that to happen (polling CFUN/COPS or enabling AT+CREG), otherwise you risk waiting too short time. See the 27.007 specification for more information for those commands.
Second do not use delay
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Please do not write code like this. See this answer on why using delay is such a bad idea, and this answer for suggestion to how to handle properly.

Resources