T68i wysyłanie i odbiór sms

Masz problem, z którym nie możesz sobie poradzić? Pisz śmiało!
ODPOWIEDZ
wachu
Młodszy majsterkowicz
Posty: 23
Rejestracja: 25 wrz 2012, 23:02

T68i wysyłanie i odbiór sms

Post autor: wachu » 16 gru 2012, 23:26

Ostatnio odkurzyłem mój stary telefon Sony Ericsson T68i i postanowiłem go wykorzystać do swojego projektu. Na początek chciałbym aby po odebraniu sms'a np. TEMP wysyłał aktualną temperaturą pobraną z czujników. W necie znalazłem sposób podłączenia oraz program z kodowaniem sms'a do formatu PDU bo tylko taki jest obsługiwany przez ten model. Nie mam dużych problemów z wysyłaniem wiadomości sms, generalnie działa poniższy kod (te zdefiniowane zmienne na początku służą tylko do zmiany testu sms'a na format PDU, ale równie dobrze można zastosować gotową wiadomość w formacie PDU i ją wysłać za pomocą mniej niż 10 linii kodu):

Kod: Zaznacz cały

#include <NewSoftSerial.h>
#define num_to_char(number)   ((number) < 10 ?                           \
                                               ('0' + (number)) :        \
                                               (('A' - 10) + (number)) )

/* To select the 4 bits we do this */
#define first_four(byte)       (0x0F & (byte))

/* Last four: Shift left to get to a number < 16 */
#define  last_four(byte)      ((0xF0 & (byte)) >> 4)

/* The MSB goes first. */
#define hexdump_a(byte)  num_to_char( last_four(byte))
#define hexdump_b(byte)  num_to_char(first_four(byte))
/*
 */
 
NewSoftSerial cell(2,3); //pin 2 is Rx pin 3 is Tx
int incomingByte=0;
int incomingByteSerial=0;


const int buttonPin = 8;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
int buttonState = 0; 

int timesToSend = 1;        // Numbers of SMS to send
int count = 0;
int licznik=0;
char* myStrings[]={"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};

void setup(){
  pinMode(ledPin, OUTPUT);      // initialize the LED pin as an output:
  pinMode(buttonPin, INPUT);    // initialize the pushbutton pin as an input: 

Serial.begin(9600);               
cell.begin(4800);// the GPRS baud rate
Serial.println("Communication is Starting...");
 Serial.println("AT");
 cell.println("AT"); 
 delay(500);
 Serial.println("Wybor formatu PDU: AT+CMGF=0");
 cell.println("AT+CMGF=0");
  delay(500);

Serial.println("Zapytanie o aktulany format: AT+CMGF=?");
 cell.println("AT+CMGF=?");
  delay(500);
  Serial.print("Otrzymana odpowiedz: ");
   incomingByte = cell.read();
    Serial.println(incomingByte, DEC); 
    Serial.println("Wybor pamieci telefonu: AT+CPMS=ME");
    cell.println("AT+CPMS=\"ME\"");
    delay(1500);
     Serial.println("Nadus przycisk");  
}

void loop(){
  if (cell.available()>0)
  {
    Serial.println("Jest wiadomosc lub tylko jest obecny telefon");
    Serial.print("Otrzymalem: ");  
  cell.println("AT");
  delay(500);
    incomingByte = cell.read();
    Serial.print("odczyt z po poleceniu AT: ");
    Serial.println(incomingByte, DEC);    
  }
  
  if (Serial.available()>0)
  {
    Serial.print("Odczyt z serialu: ");
    incomingByteSerial= Serial.read();
    Serial.println(incomingByteSerial, DEC);
  }
 
  buttonState = digitalRead(buttonPin);  // read the state of the pushbutton value:

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {     
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
     send_sms(myStrings[licznik]);
     licznik++;
     delay(1500);
     deleteAllMsgs();
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
  }
 }

void hexdump_byte(unsigned char byte)
{
  cell.print(hexdump_a(byte), BYTE);  
  Serial.print(hexdump_a(byte), BYTE);  
  cell.print(hexdump_b(byte), BYTE);
  Serial.print(hexdump_b(byte), BYTE);
}

//***** wysyłanie sms'a**********
void send_sms(char *data)
{
  size_t data_length, x;
  char c, l;
  long i;
  long n;

  data_length = strlen(data);
  i = data_length * 7;

  /* Round i up to a multiple of 8 */
  if (i & 0x07) i = (i & ~0x07) + 0x08;

  /* Calculate the number of message octets */
  i = i / 8;

Serial.println("Wysylanie sms'a");
  cell.println("AT+CMGF=0");
  delay(1500);
  Serial.println("AT+CMGF=0");
    cell.print("AT+CMGS=");
  delay(1500);
  Serial.print("AT+CMGS=");
  cell.println(i + 14);
  delay(1500);
  Serial.println(i + 14);
cell.print("0011000B918497522815F20000AA"); // E51
Serial.print("0011000B918497522815F20000AA");
  hexdump_byte(data_length & 0xFF);

  l = 0;
  n = 0;

  for (x = 0; x < data_length; x++)
  {
    if (data[x] == '$')  data[x] = 0x02;

    n |= (data[x] & 0x7F) << l;
    l += 7;

    if (l >= 8)
    {
      hexdump_byte(n & 0xFF);
      l -= 8;
      n >>= 8;
    }
  }

  if (l != 0)
  {
    hexdump_byte(n & 0xFF);
  }

  cell.println(0x1A, BYTE);
  Serial.println(0x1A, BYTE);
  Serial.println("Wyslano");
  
}

//****** kasowanie sms'a *******
void deleteAllMsgs() {
  Serial.println("Kasowanie po wyslaniu: AT+CMGD=1");
  cell.println("AT+CMGD=1");
  delay(1500);
  Serial.println("Skasowano. Czekam na nastepne polecenia.");
  
}
Po uruchomieniu i następnie naduszeniu przycisku otrzymuję, zgodnie z programem:

Kod: Zaznacz cały

Communication is Starting...
AT
Wybor formatu PDU: AT+CMGF=0
Zapytanie o aktulany format: AT+CMGF=?
Otrzymana odpowiedz: 0
Wybor pamieci telefonu: AT+CPMS=ME
Kasowanie pierwszej wiadomosci w pmamieci: AT+CMGD=1
Nadus przycisk
Wysylanie sms'a
AT+CMGF=0
AT+CMGS=28
0011000B918497522815F20000AA1054747A0E4ACF4173BA3CED3E8362
Wyslano
Kasowanie po wyslaniu: AT+CMGD=1
Skasowano. Czekam na nastepne polecenia.
Za to nie mogę sobie poradzić z odbieraniem wiadomości. Np. po komendzie AT powinienem otrzymać OK ale fragment kodu:

Kod: Zaznacz cały

if (cell.available()>0)
  {
    Serial.println("Jest wiadomosc lub tylko jest obecny telefon");
    Serial.print("Otrzymalem: ");  
  cell.println("AT");
  delay(500);
    incomingByte = cell.read();
    Serial.print("odczyt z po poleceniu AT: ");
    Serial.println(incomingByte, DEC);    
  }
w ogóle tego nie czyta.

Z ciekawości podłączyłem ten model bluethoot'em do HyperTerminala i sprawdziłem jakie polecenia działają i co otrzymuję w odpowiedzi. W HT po komendzie AT otrzymuję OK.

Jeżeli w serial monitorze Arduino wpiszę cokolwiek to po zadziałaniu fragmentu kodu:

Kod: Zaznacz cały

  if (Serial.available()>0)
  {
    Serial.print("Odczyt z serialu: ");
    incomingByteSerial= Serial.read();
    Serial.println(incomingByteSerial, DEC);
  }
 
wysyłanie sms'a również przestaje działać i zadziała wówczas tylko restart arduino.

Powyższy program działa w wersji 0022 po drobnych modyfikacja (biblioteka) działa też w 1.01, niemniej jednak odczyt z telefonu dalej nie działa.
Ma ktoś z Was pomysł jak to ugryźć -odczyt z telefonu?

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


Awatar użytkownika
Maxik
Starszy majsterkowicz
Posty: 405
Rejestracja: 6 lip 2012, 18:27
Lokalizacja: Gdańsk
Kontakt:

Re: T68i wysyłanie i odbiór sms

Post autor: Maxik » 17 gru 2012, 00:04

Serial.read() odczytuje tylko pierwszy bajt odebranych danych. Tu jest rozwiązanie: http://forums.adafruit.com/viewtopic.php?f=8&t=9918
wachu
Młodszy majsterkowicz
Posty: 23
Rejestracja: 25 wrz 2012, 23:02

Re: T68i wysyłanie i odbiór sms

Post autor: wachu » 17 gru 2012, 19:42

Maxik, sprawdziłem ten kod (jak widać w komentarzach zarówno podłączając z biblioteką NewSoftSerial oraz bezpośrednio do Rx i Tx na Arduino):

Kod: Zaznacz cały

#include <NewSoftSerial.h>
#define INLENGTH 16
#define INTERMINATOR 13
char inString[INLENGTH+1];
int inCount;
        
//NewSoftSerial cell= NewSoftSerial(2,3); //Rx, Tx
         
void setup() 
{
 pinMode(13, OUTPUT);
 //cell.begin(9600);
 Serial.begin(9600);
 //cell.println("AT");
 Serial.println("AT");
}
         
void loop()
{
Serial.println("AT");
 inCount = 0;
    do 
     {
     // Serial.println("Petla do");
      while (!Serial.available());             // wait for input
      inString[inCount] = Serial.read();       // get it
      if (inString [inCount] == INTERMINATOR) break;
      } while(true);
  (++inCount < INLENGTH);
  inString[inCount] = 0;                     // null terminate the string
 // Serial.println(inString);
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);              // wait for a second 
 }
Na powyższym pętla do działa nieprzerwanie.

Sprawdziłem też ten kod:

Kod: Zaznacz cały

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600); // Initialize serial port
  Serial.println("AT");
  delay(500);
  Serial.println("AT+CNMI=3,3");
  delay(500);
  Serial.println("AT");
}

void loop()
{

  serialReader(); 
}

void serialReader(){
  int makeSerialStringPosition;
  int inByte;
  char serialReadString[50];
  const int terminatingChar = 13; //Terminate lines with CR

  inByte = Serial.read();
  makeSerialStringPosition=0;

  if (inByte > 0 && inByte != terminatingChar) { //If we see data (inByte > 0) and that data isn't a carriage return
    delay(100); //Allow serial data time to collect (I think. All I know is it doesn't work without this.)

    while (inByte != terminatingChar && Serial.available() > 0){ // As long as EOL not found and there's more to read, keep reading
      serialReadString[makeSerialStringPosition] = inByte; // Save the data in a character array
      makeSerialStringPosition++; //Increment position in array
      //if (inByte > 0) Serial.println(inByte); // Debug line that prints the charcodes one per line for everything recieved over serial
      inByte = Serial.read(); // Read next byte
    }

    if (inByte == terminatingChar) //If we terminated properly
    {
      serialReadString[makeSerialStringPosition] = 0; //Null terminate the serialReadString (Overwrites last position char (terminating char) with 0
      Serial.println(serialReadString);
      if (strcmp(serialReadString, "LEDOn") == 0) digitalWrite(13, HIGH);
      if (strcmp(serialReadString, "LEDOff") == 0) digitalWrite(13, LOW);
    }
  } 
}
a także taki:

Kod: Zaznacz cały

#include <NewSoftSerial.h>
NewSoftSerial modem(2,3); // 2 is the RX pin, 3 is the TX pin

void setup()
{
   modem.begin(9600);
   Serial.begin(9600);
   modem.println("AT");
   while(millis() < 30000) // wait for a reply for up to 30 seconds
   {
     while(modem.available() > 0)
      {
         char aChar = modem.read();
         Serial.println(aChar);
      }
   }
}

void loop()
{
  
}
i niestety (przepraszam) za cholerę nie idzie *&(*&^!!!! (aż mnie szlak jasny, pioruny ...)

Jakieś inne pomysły?
wachu
Młodszy majsterkowicz
Posty: 23
Rejestracja: 25 wrz 2012, 23:02

Re: T68i wysyłanie i odbiór sms

Post autor: wachu » 18 gru 2012, 23:23

Kod środkowy który przytoczyłem wyżej pochodzący z odnośnika podanego przez Maxik'a czyta polecenia LEDOn i LEDOff z serial monitor, jednak dalej nie czyta z T68i:

Kod: Zaznacz cały

#include <NewSoftSerial.h>
NewSoftSerial cell(2,3); //pin 2 is Rx pin 3 is Tx

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600); // Initialize serial port
  cell.begin(9600);
    cell.println("AT");
    delay(500);
    cell.println("AT");
    delay(500);
    cell.println("AT+CMGF=0");
  delay(500);
cell.println("AT+CMGF=0");
  delay(500);
  cell.println("AT+CMGF=?");
}

void loop()
{

  serialReader(); 
}

void serialReader(){
  
  int makeSerialStringPosition;
  int inByte;
  char serialReadString[50];
  const int terminatingChar = 13; //Terminate lines with CR

  inByte = cell.read();
  makeSerialStringPosition=0;

  if (inByte > 0 && inByte != terminatingChar) { //If we see data (inByte > 0) and that data isn't a carriage return
    delay(100); //Allow serial data time to collect (I think. All I know is it doesn't work without this.)

    while (inByte != terminatingChar && cell.available() > 0){ // As long as EOL not found and there's more to read, keep reading
      serialReadString[makeSerialStringPosition] = inByte; // Save the data in a character array
      makeSerialStringPosition++; //Increment position in array
      //if (inByte > 0) Serial.println(inByte); // Debug line that prints the charcodes one per line for everything recieved over serial
      inByte = cell.read(); // Read next byte
    }

    if (inByte == terminatingChar) //If we terminated properly
    {
      serialReadString[makeSerialStringPosition] = 0; //Null terminate the serialReadString (Overwrites last position char (terminating char) with 0
      Serial.println(serialReadString);
      if (strcmp(serialReadString, "OK") == 0) digitalWrite(13, HIGH);
      if (strcmp(serialReadString, "LEDOff") == 0) digitalWrite(13, LOW);
    }
  } 
}

Wcześniej nie pokazałem, robię to teraz, telefon podłączony mam kablem DCU-11 i zgodnie z rozkładem pinów jak na załączonym zdjęciu niżej.

Podłączenie na moim kablu:
biały - pin 4 w telefonie czyli Rx (podłączony do pinu 3 arduino)
niebieski - pin 5 w telefonie czyli Tx (podłączony do pinu 2 arduino -jak go odłączę to wysyłanie sms'a i tak działa)
zielony - pin 10 w telefonie czyli GDN (podłączony do pinu GDN cyfrowego)
żółty - pin 11 w telefonie czyli VCC (podłączony lub nie do V5 arduino -załącza się tylko ładowanie nie ma wpływu na wysyłanie)
czerwony - nie podłączony nigdzie sprawdzając miernikiem jest podłączony do pinu 7 i 8 w telefonie

Zastanawiam się nad tym czerwonym, w opisie pinów na stronie: http://pinouts.ru/CellularPhones-P-W/er ... nout.shtml, podane jest w komentarzu, że w niektórych modelach np. T68 (mój model to T68i) jest jako Tx ale fakt, że do flashowania.

Jakieś pomysły jak odczytać dane po komendzie np. AT ?
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
wachu
Młodszy majsterkowicz
Posty: 23
Rejestracja: 25 wrz 2012, 23:02

Re: T68i wysyłanie i odbiór sms

Post autor: wachu » 18 gru 2012, 23:30

a i jeszcze screen z działania Hyper Terminala po bluetooth'cie pokazujący, że telefon odpowiada na komendy AT jak niżej na zdjęciu.

Dokonując pomiarów miernikiem po podłączeniu kabla tylko do telefonu mam pomiędzy zielonym a:
biały ~0V
niebieski ~2.8V
czerwony ~0.7V

Może podobnie jak w poście: http://www.elektroda.pl/rtvforum/topic1 ... ml#8340190 powinienem wstawić rezystor pomiędzy niebieskim a pinem 2 arduino?
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Maxik
Starszy majsterkowicz
Posty: 405
Rejestracja: 6 lip 2012, 18:27
Lokalizacja: Gdańsk
Kontakt:

Re: T68i wysyłanie i odbiór sms

Post autor: Maxik » 19 gru 2012, 17:55

Ten kod czeka na znak CR, czyli upraszczając Enter. Zobacz w jaki sposób telefon kończy linię i przystosuj kod. Dodatkowo możesz wykorzystać bibliotekę String z Arduino i pakować do tego Stringa tyle znaków ile akurat wyśle telefon, bez odgórnego ograniczania jego długości.
wachu
Młodszy majsterkowicz
Posty: 23
Rejestracja: 25 wrz 2012, 23:02

Re: T68i wysyłanie i odbiór sms

Post autor: wachu » 20 gru 2012, 02:29

Maxik, dzięki za zainteresowanie i sugestie. Sprawdziłem w specyfikacji komend i jest:
Command-Line Editing Character =8, Command Line Termination Character=13 CR, Response Formatting Character=10 LF
Obecny kod testowy jak niżej, sprawdzałem dla 8, 10 i 13 niestety dalej nic z odczytem.
Dziwne bo w HT po komendzie AT+GMM pokazał mi T68 a nie T68i -ten telefon był kiedyś tam w serwisie bo się zawieszał i miał zmieniane oprogramowanie. Czytałem na elektrodzie, że można wgrać soft z T68 do T68i - może tu jest pies pogrzebany. Coś jest popieprzone we firmware'rze tego telefonu i nie mogę odczytać nic po serialu, może Tx jest na innym pinie?
Dzisiaj już trochę późno (albo za wcześnie;-) ale jutro ostatnia szansa - sprawdzę ten czerwony przewód.

Kod: Zaznacz cały

#include <NewSoftSerial.h>
NewSoftSerial cell(2,3); //pin 2 is Rx pin 3 is Tx
unsigned long time;

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600); // Initialize serial port
  cell.begin(4800);
    cell.println("AT");
    delay(500);
    cell.println("ATE=0"); //wyłączenie echa
    delay(500);
    cell.println("AT");
    delay(500);
  //  cell.println("AT+CMGF=0");
  //delay(500);
cell.println("AT+CBST=6"); //ustawienie transmisji 4800 bits/s V.32
  delay(500);
 cell.println("ATD=xxxxxx;");//xxx to mój nr telfonu modem dzwoni bez problemu
}

void loop()
{
time=millis();
if ((time%2000)==0)
{
   Serial.println("Podalem: AT+GMM");
  cell.println("AT+GMM"); //zwraca model telefonu w HT pokazuje T68
  delay(500);
}
  serialReader(); 
}

void serialReader(){
  
  int makeSerialStringPosition;
  int inByte;
  char serialReadString[50];
  const int terminatingChar = 8; //Command-Line Editing Character =8, Command Line Termination Character=13 CR, Response Formatting Character=10 LF

  inByte = cell.read();
  makeSerialStringPosition=0;

  if (inByte > 0 && inByte != terminatingChar) { //If we see data (inByte > 0) and that data isn't a carriage return
    delay(100); //Allow serial data time to collect (I think. All I know is it doesn't work without this.)

    while (inByte != terminatingChar && cell.available() > 0){ // As long as EOL not found and there's more to read, keep reading
      serialReadString[makeSerialStringPosition] = inByte; // Save the data in a character array
      makeSerialStringPosition++; //Increment position in array
      //if (inByte > 0) Serial.println(inByte); // Debug line that prints the charcodes one per line for everything recieved over serial
      inByte = cell.read(); // Read next byte
    }

    if (inByte == terminatingChar) //If we terminated properly
    {
      serialReadString[makeSerialStringPosition] = 0; //Null terminate the serialReadString (Overwrites last position char (terminating char) with 0
      Serial.println(serialReadString);
      if (strcmp(serialReadString, "OK") == 0) digitalWrite(13, HIGH);
      if (strcmp(serialReadString, "LEDOff") == 0) digitalWrite(13, LOW);
    }
  } 
}
wachu
Młodszy majsterkowicz
Posty: 23
Rejestracja: 25 wrz 2012, 23:02

Re: T68i wysyłanie i odbiór sms

Post autor: wachu » 21 gru 2012, 23:02

znalazłem jeszcze jeden kod: http://playground.arduino.cc/Main/SonyEricsson, który też nie działa.
Reasumując T68i z Arduino pozwala tylko na wysyłanie sms'ów i ewentualne dzwonienie. Jak mi się uda zdobyć T230 lub T300 to spróbuję jeszcze raz.
ODPOWIEDZ

Strony partnerskie: