Updated--Issue with sensors connecting to Arduino Uno via Atlas Scientific hardware serial port expander 8:1 - gps

Hardware connection and also programming issue with sensors (GPS NEO-6M module, ESP8266 etc.) connecting to Arduino Uno via Atlas Scientific serial port expander 8:1
Hardware:
Arduino Uno
Atlas Scientific serial port expander 8:1
GPS NEO-6M module
ESP8266 Wifi module
Arduino Uno to GPS module we are able to get latitude and longitude values, below is the code for the same:
#include <SoftwareSerial.h>
#include <TinyGPS.h>
long lat, lon;
SoftwareSerial gpsSerial(6, 5);
TinyGPS gps;
void setup() {
Serial.begin(9600);
gpsSerial.begin(9600);
}
void loop() {
while (gpsSerial.available()) {
if (gps.encode(gpsSerial.read())) {
gps.get_position(&lat, &lon);
Serial.print("Position:");
Serial.print("lat:"); Serial.print(lat); Serial.print(" ");
Serial.print("long:"); Serial.println(lon);
}
}
}
Our requirement is that we have four sensors that need to be connected to an Arduino Uno. For that we used an Atlas Scientific hardware serial port expander 8:1.
Below is the code which we are working to get the GPS coordinates:
#include <SoftwareSerial.h> // we have to include the SoftwareSerial library, or else we can't use it
#define rx 8 // define what pin rx is going to be
#define tx 9 // define what pin tx is going to be
SoftwareSerial mySerial(rx, tx); //define how the soft serial port is going to work
int s1 = 6; // Arduino pin 6 to control pin S1
int s2 = 5; // Arduino pin 5 to control pin S2
int s3 = 4; // Arduino pin 4 to control pin S3
const uint8_t module_count = 8; // number of modules connected to the serial port expander 1=Port1, 2= Port2 and so on
void setup() {
Serial.begin(115200); // Set the hardware serial port to 115200
mySerial.begin(9600); // Set baud rate for the software serial port to 9600
pinMode(s1, OUTPUT); // Set the digital pin as output
pinMode(s2, OUTPUT); // Set the digital pin as output
pinMode(s3, OUTPUT); // Set the digital pin as output
}
void loop() {
if (Serial.available()) { // if we get data from the computer
char c = Serial.read();
for (uint8_t i = 1; i <= module_count; i++) { // loop through the modules
Serial.print("Connecting to Port: ");
Serial.println(i);
open_port(i); // open the port
mySerial.print(c); // print character to port
delay(100); // insert a delay to wait for the reply
if (mySerial.available()) { // print reply to serial monitor
while (mySerial.available()) {
Serial.println(mySerial.read());
if (gps.encode(mySerial.read())) {
gps.get_position(&lat, &lon);
Serial.print("Position:");
Serial.print("lat:"); Serial.print(lat);
Serial.print(" ");
Serial.print("long:"); Serial.println(lon);
}
}
}
else {
Serial.print("No response received");
}
Serial.println();
}
}
}
void open_port(uint8_t _port) { //this function controls what port is opened on the serial port expander
if (_port < 1 || module_count > 8)_port = 1; //if the value of the port is within range (1-8) then open that port. If it's not in range set it to port 1
uint8_t port_bits = _port - 1;
digitalWrite(s1, bitRead(port_bits, 0)); //Here we have two commands combined into one.
digitalWrite(s2, bitRead(port_bits, 1)); //The digitalWrite command sets a pin to 1/0 (high or low)
digitalWrite(s3, bitRead(port_bits, 2)); //The bitRead command tells us what the bit value is for a specific bit location of a number
delay(2); //this is needed to make sure the channel switching event has completed
}
Kindly guide us in sorting the issue; we are having an issue with gps.encode(mySerial.read()).
Thank you in advance.

Issue was sorted out by ourselves,
Below is the working code for the same ,
#include <SoftwareSerial.h> //we have to include the SoftwareSerial library, or else we can't use it
#define rx 3 //define what pin rx is going to be
#define tx 2 //define what pin tx is going to be
SoftwareSerial mySerial(rx, tx); //define how the soft serial port is going to work
#include <TinyGPS.h>
#include <NMEAGPS.h>
int s1 = 6; //Arduino pin 6 to control pin S1
int s2 = 5; //Arduino pin 5 to control pin S2
int s3 = 4; //Arduino pin 4 to control pin S3
int i;
const uint8_t module_count = 8; //number of modules connected to the serial port expander 1=Port1, 2= Port2 and so on
TinyGPS gps;
gps_fix fix;
long lat, lon;
void setup() {
Serial.begin(9600); //Set the hardware serial port to 115200
mySerial.begin(9600); //set baud rate for the software serial port to 9600
pinMode(s1, OUTPUT); //Set the digital pin as output
pinMode(s2, OUTPUT); //Set the digital pin as output
pinMode(s3, OUTPUT); //Set the digital pin as output
}
void loop() {
if (Serial.available()) { //if we get data from the computer
char c = Serial.read();
for (uint8_t i = 1; i <= module_count; i++) { // loop through the modules
Serial.print("Connecting to Port: ");
Serial.println(i);
open_port(i); // open the port
Serial.print(c); //print character to port
delay(1000); //insert a delay to wait for the reply
//Serial.println(Serial.available());
if (Serial.available()) {
//Serial.println(gps.available(Serial));//print reply to serial monitor
while (Serial.available()) {
//Serial.write(mySerial.read());
//Serial.write(gps.encode(mySerial.read()));
//Serial.println(mySerial.available());
//Serial.println(gps.encode(mySerial.read()));
if (mySerial.available()>0) {
//Serial.println(gps.encode(mySerial.read()));
char d = byte(mySerial.read());
//Serial.println(d);
if (gps.encode(d)) {
gps.get_position(&lat, &lon);
Serial.print("Position:");
Serial.print("lat:"); Serial.print(lat); Serial.print(" ");
Serial.print("long:"); Serial.println(lon);
}
}
}
Serial.println();
}
}
}
}
void open_port(uint8_t _port) { //this function controls what port is opened on the serial port expander
if (_port < 1 || module_count > 8)_port = 1; //if the value of the port is within range (1-8) then open that port. If it's not in range set it to port 1
uint8_t port_bits = _port - 1;
digitalWrite(s1, bitRead(port_bits, 0)); //Here we have two commands combined into one.
digitalWrite(s2, bitRead(port_bits, 1)); //The digitalWrite command sets a pin to 1/0 (high or low)
digitalWrite(s3, bitRead(port_bits, 2)); //The bitRead command tells us what the bit value is for a specific bit location of a number
delay(2); //this is needed to make sure the channel switching event has completed
}

Related

Problem arduino uno sketch and sim 800l modem

The code works ok on the serial monitor and I can ses in the serial monitor that the code makes the AT command for sending a reply by sms but it doesn't send and I can't control the sketch by SMS.
I can't figure out what goes wrong. It's a long sketch so I try to set the parts of the code where the code is for the modem.
#include <SoftwareSerial.h>
const uint8_t rxPin = 2;
const uint8_t txPin = 3;
SoftwareSerial sim800(2, 3); // SIM800L rx og tx til pin 2 and 3
#define sim800 Serial
void setup() {
Serial.begin(9600);
while (!Serial) {
; // Wait for serial monitor to open
}
sim800.begin(9600);
while (!sim800) {
; // Wait for SIM800L module to start
}
sim800.println("AT");
delay(1000);
// Read response from SIM800L module
while (sim800.available()) {
String response = sim800.readString();
Serial.println(response);
if (sim800.available())
{
String message = sim800.readString();
Serial.println(message);
message.trim();
message.toUpperCase();
if(message.indexOf("ARM") >= 0) // ARM DISARM COMMAND
{
if(message.indexOf("DISARM") == 0)
{
armed = false;
send_SMS("DISARMED!");
void send_SMS(const char *message)
{
sim800.println("AT+CMGF=1"); // Set SMS mode to text
delay(100);
sim800.println("AT+CMGS=\"+123456789\""); // telefon nummer
sim800.println(message);
sim800.println((char)26); // send SMS
I can't figure out where the error is.

Mpu6050 and Adafruit Ultimate Gps not working together on Arduino Due

I have the codes for mpu6050 and adafruit ultimate gps breakout v3 and they are working fine seperately on arduino due but when i try to combine both the codes the gps does not get a fix. Can anybody help me out?
The code for mpu6050 is given below
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
extern TwoWire Wire1;
const int MPU_addr=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;
double pitch,roll,delta_X,delta_Y,delta_Z;
double old_AcX=0;
double old_AcY=0;
double old_AcZ=0;
int led = 13;
void setup(){
Wire1.begin();
Wire1.beginTransmission(MPU_addr);
Wire1.write(0x6B); // PWR_MGMT_1 register
Wire1.write(0); // set to zero (wakes up the MPU-6050)
Wire1.endTransmission(true);
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
Wire1.beginTransmission(MPU_addr);
Wire1.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire1.endTransmission(false);
Wire1.requestFrom(MPU_addr,14,true); // request a total of 14 registers
AcX=Wire1.read()<<8|Wire1.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire1.read()<<8|Wire1.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire1.read()<<8|Wire1.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire1.read()<<8|Wire1.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire1.read()<<8|Wire1.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire1.read()<<8|Wire1.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire1.read()<<8|Wire1.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
Serial.print("AcX = "); Serial.print(AcX);
Serial.print(" | AcY = "); Serial.print(AcY);
Serial.print(" | AcZ = "); Serial.print(AcZ);
Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //equation for temperature in degrees C from datasheet
Serial.print(" | GyX = "); Serial.print(GyX);
Serial.print(" | GyY = "); Serial.print(GyY);
Serial.print(" | GyZ = "); Serial.println(GyZ);
delay(1000);
}
And the code for the Adafruit ultimate Gps breakout is given below
#include <Adafruit_GPS.h>
#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);
#define GPSECHO true
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
void setup()
{
Serial.begin(9600);
GPS.begin(9600);
mySerial.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
GPS.sendCommand(PGCMD_ANTENNA);
#ifdef __arm__
usingInterrupt = false;
#else
useInterrupt(true);
#endif
delay(1000);
}
#ifdef __AVR__
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.
#endif
}
void useInterrupt(boolean v) {
if (v) {
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
#endif //#ifdef__AVR__
uint32_t timer = millis();
void loop()
{
if (! usingInterrupt) {
char c = GPS.read();
}
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trytng to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
}
// if millis() or timer wraps around, we'll just reset it
if (timer > millis()) timer = millis();
// approximately every 2 seconds or so, print out the current stats
if (millis() - timer > 2000) {
timer = millis(); // reset the timer
Serial.print("\nTime: ");
Serial.print(GPS.hour, DEC); Serial.print(':');
Serial.print(GPS.minute, DEC); Serial.print(':');
Serial.print(GPS.seconds, DEC); Serial.print('.');
Serial.println(GPS.milliseconds);
Serial.print("Date: ");
Serial.print(GPS.day, DEC); Serial.print('/');
Serial.print(GPS.month, DEC); Serial.print("/20");
Serial.println(GPS.year, DEC);
Serial.print("Fix: "); Serial.print((int)GPS.fix);
Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
if (GPS.fix) {
//Serial.print("Location: ");
Serial.print(convertDegMinToDecDeg(GPS.latitude));
Serial.print(", ");
Serial.println(convertDegMinToDecDeg(GPS.longitude));
//Serial.print("Speed (knots): "); Serial.println(GPS.speed);
//Serial.print("Angle: "); Serial.println(GPS.angle);
//Serial.print("Altitude: "); Serial.println(GPS.altitude);
//Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
}
}
}
Both the codes are working fine separetely but i am unable to combine them and run in a single code.I tried to combine them and tha adafruit Ultimate gps breakout isn't working and it gives nothing. I want to know how i can combine them to work in a single code.Thanks in advance.
Use NeoGPS instead -- just add it to your IMU sketch:
#include <NMEAGPS.h>
NMEAGPS gps;
#define gpsPort Serial1
...
void setup(){
Wire1.begin();
Wire1.beginTransmission(MPU_addr);
Wire1.write(0x6B); // PWR_MGMT_1 register
Wire1.write(0); // set to zero (wakes up the MPU-6050)
Wire1.endTransmission(true);
Serial.begin(9600);
pinMode(led, OUTPUT);
gpsPort.begin( 9600 );
}
void loop(){
if (gps.available( gpsPort )) {
gps_fix fix = gps.read(); // A new GPS update is ready, get all the pieces
// Print some of the pieces?
Serial.print( F("Location: ") );
if (fix.valid.location) {
Serial.print( fix.latitude(), 6 );
Serial.print( ',' );
Serial.print( fix.longitude(), 6 );
}
Serial.print( F(", Altitude: ") );
if (fix.valid.altitude)
Serial.print( fix.altitude() );
Serial.println();
// Take an IMU sample too.
Wire1.beginTransmission(MPU_addr);
...
Serial.print(" | GyZ = "); Serial.println(GyZ);
}
}
This will display one GPS update and one IMU sample per second.
Also, you cannot use delay. The Arduino will not do anything else during the delay, and it will lose GPS characters. Notice that the above loop structure is always running, checking for GPS data. When a GPS update is finally ready, it takes the IMU sample and prints all the results.
You also have to be careful about printing too much information. Eventually, the Arduino will spend all its time waiting to print characters.
NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch -> Include Library -> Manage Libraries. NeoGPS is faster, smaller, more reliable and more accurate than all other GPS libraries, and the examples are properly structured. It is very common for the other libraries' examples to break when they are modified. Even if you don't use it, there is lots of information on the NeoGPS Installation and Troubleshooting pages.

Sensor reading communication via bluetooth

I have two bluetooth modules(HC05) connected to separate arduinos. One acting as master and other as slave. One LDR is connected to the slave part which will be taking continuous readings and sending it to master via bluetooth.
The modules are successfully paired.I could even control an led connected to master using a pushbutton connected to slave.
Since 4 days I am struggling to get the readings of LDR on the serial monitor of master.
The slave part of the project(having the LDR):
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
#define ldrPin A0
int ldrValue = 0;
void setup() {
pinMode(9, OUTPUT); // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
digitalWrite(9, HIGH);
pinMode(ldrPin, INPUT);
BTSerial.begin(9600);
Serial.begin(9600);
}
void loop()
{
ldrValue = analogRead(ldrPin);
BTSerial.println(ldrValue);
Serial.println(ldrValue);
delay(1000);
}
The master part of the project which will be getting the reaings and displaying on serial monitor:
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
const byte numChars = 1024;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
void setup() {
pinMode(9, OUTPUT); // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
digitalWrite(9, HIGH);
BTSerial.begin(9600);
Serial.begin(9600);
Serial.println("<Arduino is ready>");
}
void loop() {
recvWithEndMarker();
showNewData();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (BTSerial.available() > 0 && newData == false) {
rc = BTSerial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void showNewData() {
if (newData == true) {
Serial.print("This just in ... ");
Serial.println(receivedChars);
newData = false;
}
}
But the problem is that in the serial monitor only the highest digit ( 3 in 392) is displayed in the serial monitor. The readings are correct but the complete readings are not displayed.
The serial monitor showed something like this:
<Arduino is ready>
This just in ... 1
This just in ... 1
This just in ... 1
This just in ... 1
This just in ... 1
This just in ... 3
This just in ... 3
This just in ... 3
This just in ... 3
This just in ... 3
Ifin the Slave part instead of LDR readings if I am sending a string "hello", then it is printing as :
<Arduino is ready>
This just in ... h
This just in ... h
This just in ... h
This just in ... h
This just in ... h
This just in ... h
I have referred this link for serial communications Serial input basics
Can someone please help me out as I am new to arduino.
To read a string directly into a variable you can use:
BTSerial.readString()
instead of:
BTSerial.read()
like in the official documentation

Unable to run input cature mode with SPI

I am Trying to run a web-server on AVR ATmega8 using ENC28J60 module. For this I got sample code from here. This code is working fine. Here is my code:-
#define F_CPU 8000000UL
#include <avr/io.h>
#include <string.h>
#include "ip_arp_udp_tcp.h"
#include "enc28j60.h"
#include "timeout.h"
#include "avr_compat.h"
#include "net.h"
// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
static uint8_t myip[4] = {192,168,24,39};
// listen port for www
#define MYWWWPORT 80
//// listen port for udp
#define MYUDPPORT 1200
//
#define BUFFER_SIZE 450
static uint8_t buf[BUFFER_SIZE+1];
int main(void)
{
uint16_t plen;
uint16_t dat_p;
uint8_t i=0;
uint8_t payloadlen=0;
_delay_loop_1(50);
/*initialize enc28j60*/
enc28j60Init(mymac);
enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
_delay_loop_1(50); // 12ms
enc28j60PhyWrite(PHLCON,0x476);
_delay_loop_1(50); // 12ms
//init the ethernet/ip layer:
init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);
while(1)
{
// get the next new packet:
plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
/*plen will ne unequal to zero if there is a valid * packet (without crc error) */
if(plen==0)
{
continue;
}
// arp is broadcast if unknown but a host may also
// verify the mac address by sending it to
// a unicast address.
if(eth_type_is_arp_and_my_ip(buf,plen))
{
make_arp_answer_from_request(buf);
continue;
}
// check if ip packets (icmp or udp) are for us:
if(eth_type_is_ip_and_my_ip(buf,plen)==0)
{
continue;
}
if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
{
// a ping packet, let's send pong
make_echo_reply_from_request(buf,plen);
continue;
}
// tcp port www start, compare only the lower byte
if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT)
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
{
make_tcp_synack_from_syn(buf);
// make_tcp_synack_from_syn does already send the syn,ack
continue;
}
if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
{
init_len_info(buf); // init some data structures
// we can possibly have no data, just ack:
dat_p=get_tcp_data_pointer();
if (dat_p==0)
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
{
// finack, answer with ack
make_tcp_ack_from_any(buf);
}
// just an ack with no data, wait for next packet
continue;
}
if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
{
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
}
else
{
// Web Code
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<p>PLANETCAST MEDIA SERVICES LTD</p>"));
plen=fill_tcp_data_p(buf,plen,PSTR("<body>"));
plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"text\" id=\"myurl\" name=\"url\" placeholder=\"Enter Url\"/><br>"));
plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"submit\" id=\"clickbutton\" name=\"Click Here\" />"));
plen=fill_tcp_data_p(buf,plen,PSTR("<script type=\"text/javascript\">"));
plen=fill_tcp_data_p(buf,plen,PSTR("document.getElementById(\"clickbutton\").onclick = function(){"));
plen=fill_tcp_data_p(buf,plen,PSTR("var url = document.getElementById(\"myurl\").value;"));
plen=fill_tcp_data_p(buf,plen,PSTR("location.href=url;"));
plen=fill_tcp_data_p(buf,plen,PSTR("};"));
plen=fill_tcp_data_p(buf,plen,PSTR("</script>"));
plen=fill_tcp_data_p(buf,plen,PSTR("</body"));
}
make_tcp_ack_from_any(buf); // send ack for http get
make_tcp_ack_with_data(buf,plen); // send data
continue;
}
}
// udp interface:
if (buf[IP_PROTO_P]==IP_PROTO_UDP_V)
{
payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
// the received command has to start with t and be 4 char long
// e.g "test\0"
if (buf[UDP_DATA_P]=='t' && payloadlen==5)
{
make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
}
}
}
return (0);
}
Now I want to add Input Capture Mode , so I add interrupt header file then start Input capture mode in main() and then introduce sei() function. Now My code look like this:-
#define F_CPU 8000000UL
#include <avr/io.h>
#include <string.h>
#include "ip_arp_udp_tcp.h"
#include "enc28j60.h"
#include "timeout.h"
#include "avr_compat.h"
#include "net.h"
#include <avr/interrupt.h>
// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
static uint8_t myip[4] = {192,168,24,39};
// listen port for www
#define MYWWWPORT 80
//// listen port for udp
#define MYUDPPORT 1200
//
#define BUFFER_SIZE 450
static uint8_t buf[BUFFER_SIZE+1];
int main(void)
{
TCCR1A = 0;
TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
TIMSK = (1<<TICIE1);
TCNT1 = 0;
sei();
uint16_t plen;
uint16_t dat_p;
uint8_t i=0;
uint8_t payloadlen=0;
_delay_loop_1(50);
/*initialize enc28j60*/
enc28j60Init(mymac);
enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
_delay_loop_1(50); // 12ms
enc28j60PhyWrite(PHLCON,0x476);
_delay_loop_1(50); // 12ms
//init the ethernet/ip layer:
init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);
while(1)
{
// get the next new packet:
plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
/*plen will ne unequal to zero if there is a valid * packet (without crc error) */
if(plen==0)
{
continue;
}
// arp is broadcast if unknown but a host may also
// verify the mac address by sending it to
// a unicast address.
if(eth_type_is_arp_and_my_ip(buf,plen))
{
make_arp_answer_from_request(buf);
continue;
}
// check if ip packets (icmp or udp) are for us:
if(eth_type_is_ip_and_my_ip(buf,plen)==0)
{
continue;
}
if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
{
// a ping packet, let's send pong
make_echo_reply_from_request(buf,plen);
continue;
}
// tcp port www start, compare only the lower byte
if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT)
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
{
make_tcp_synack_from_syn(buf);
// make_tcp_synack_from_syn does already send the syn,ack
continue;
}
if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
{
init_len_info(buf); // init some data structures
// we can possibly have no data, just ack:
dat_p=get_tcp_data_pointer();
if (dat_p==0)
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
{
// finack, answer with ack
make_tcp_ack_from_any(buf);
}
// just an ack with no data, wait for next packet
continue;
}
if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
{
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
}
else
{
// Web Code
plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<p>PLANETCAST MEDIA SERVICES LTD</p>"));
plen=fill_tcp_data_p(buf,plen,PSTR("<body>"));
plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"text\" id=\"myurl\" name=\"url\" placeholder=\"Enter Url\"/><br>"));
plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"submit\" id=\"clickbutton\" name=\"Click Here\" />"));
plen=fill_tcp_data_p(buf,plen,PSTR("<script type=\"text/javascript\">"));
plen=fill_tcp_data_p(buf,plen,PSTR("document.getElementById(\"clickbutton\").onclick = function(){"));
plen=fill_tcp_data_p(buf,plen,PSTR("var url = document.getElementById(\"myurl\").value;"));
plen=fill_tcp_data_p(buf,plen,PSTR("location.href=url;"));
plen=fill_tcp_data_p(buf,plen,PSTR("};"));
plen=fill_tcp_data_p(buf,plen,PSTR("</script>"));
plen=fill_tcp_data_p(buf,plen,PSTR("</body"));
}
make_tcp_ack_from_any(buf); // send ack for http get
make_tcp_ack_with_data(buf,plen); // send data
continue;
}
}
// udp interface:
if (buf[IP_PROTO_P]==IP_PROTO_UDP_V)
{
payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
// the received command has to start with t and be 4 char long
// e.g "test\0"
if (buf[UDP_DATA_P]=='t' && payloadlen==5)
{
make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
}
}
}
return (0);
}
ISR(TIMER1_CAPT_vect)
{
//do something
}
Now when I run my code , I got no webpage on my browser. So, I comment out sei() function. After this my code works fine. So, I check SPI settings in enc28j60.c. As per my knowledge SPI is not running on interrupt , so it shouldn't be affected by sei(). Here is my SPi settings in enc28j60.c:-
#define ENC28J60_CONTROL_PORT PORTB
#define ENC28J60_CONTROL_DDR DDRB
#define ENC28J60_CONTROL_CS 2
#define ENC28J60_CONTROL_SO 4
#define ENC28J60_CONTROL_SI 3
#define ENC28J60_CONTROL_SCK 5
void enc28j60Init(uint8_t* macaddr)
{
// initialize I/O
// ss as output:
ENC28J60_CONTROL_DDR |= 1<<ENC28J60_CONTROL_CS;
CSPASSIVE; // ss=0
//
ENC28J60_CONTROL_DDR |= 1<<ENC28J60_CONTROL_SI | 1<<ENC28J60_CONTROL_SCK; // mosi, sck output
cbi(ENC28J60_CONTROL_DDR,ENC28J60_CONTROL_SO); // MISO is input
//
cbi(ENC28J60_CONTROL_PORT,ENC28J60_CONTROL_SI); // MOSI low
cbi(ENC28J60_CONTROL_PORT,ENC28J60_CONTROL_SCK); // SCK low
So, can anyone tell me why my SPI mode is geting effected by sei() function and how get rid of this.
I have not read all your code but i think you are all time in interrupt. In normal mode the timer are not reset when it reach the top. Try with TCNT1 = 0; in the ISR.

how send sms by Arduino Nano and Sim900a

I try to use Arduino GSM library for sending sms.I have an Arduino Nano Board And an sim900 module and that connect together by serial port.but can't send sms.
also for testing I use this example code in Arduino website:
#include <GSM.h>
#define PINNUMBER ""
// initialize the library instance
GSM gsmAccess;
GSM_SMS sms;
void setup()
{
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("SMS Messages Sender");
// connection state
boolean notConnected = true;
// Start GSM shield
// If your SIM has PIN, pass it as a parameter of begin() in quotes
while (notConnected)
{
if (gsmAccess.begin(PINNUMBER) == GSM_READY)
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
}
void loop()
{
Serial.print("Enter a mobile number: ");
char remoteNum[20]; // telephone number to send sms
readSerial(remoteNum);
Serial.println(remoteNum);
// sms text
Serial.print("Now, enter SMS content: ");
char txtMsg[200];
readSerial(txtMsg);
Serial.println("SENDING");
Serial.println();
Serial.println("Message:");
Serial.println(txtMsg);
// send the message
sms.beginSMS(remoteNum);
sms.print(txtMsg);
sms.endSMS();
Serial.println("\nCOMPLETE!\n");
}
/*
Read input serial
*/
int readSerial(char result[])
{
int i = 0;
while (1)
{
while (Serial.available() > 0)
{
char inChar = Serial.read();
if (inChar == '\n')
{
result[i] = '\0';
Serial.flush();
return 0;
}
if (inChar != '\r')
{
result[i] = inChar;
i++;
}
}
}
It seems you are having issues using the GSM libraries that come with Arduino as they use soft serial
You can then use GSM arduino library provided by GROUND LAB
This library gives you option to select the serial port. check the documentation on wiki
/*First you have to make the gsmSMS object, the arguments are in order
*GsmSMS (#1 Name of the serial port connected to GSM (your choice),#2 the address of millis function(just copy whats there) )*/
gsmSMS myGsmSMS(Serial3,&millis,&Serial); //gsmSMS TELIT SMS
This library mentions that it is for Telit but it works for sim900 as well