Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Our apartment's maintenance service has asked me whether I could design a system for audio call when elevator has stopped. I know how people are frightened when elevator stops suddenly, especially children. I said I could. Then I designed this circuit.
This circuit has two buttons. One is to call elevator maintenance service, the other is to call apartment manager. Indeed it only calls the number that saved at the first and second location of SIM card. :-)
There is M95 Quectel GSM module and Attend SIM connector to access GSM network.
Capabilities:
System can call two seperate numbers that are saved on SIM card. On the other hand, maintenance service or manager can call number of SIM on the system. So if someone has crashed in an elevator, he or she screams and might not think call someone if he or she is panic. Someoe in apartment or service can call number on the elevator. System will answer the call after it rings three times.
The device can be powered by 12V or 24V, or both. It has two channels separated by diodes and secured by changable glass fuses.
The PCB can be ordered from PCBWAY using this link. I shared this PCB for public order:
https://www.pcbway.com/project/shareproject/W118076ASC32_FD_EECP_R02___CADCAM.html
Wish nobody needs this system!
#include <main.h>
#include <def.h>
#include <regs.h>
#include <func.c>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#INT_EXT
void EXT_isr(void)
{
if (intExtFirst==0)
{
intExtState=1;
}
}
#INT_EXT1
void EXT1_isr(void)
{
if (intExtFirst==0)
{
intExt1State=1;
}
}
#INT_RDA
void RDA_isr(void)
{
intRdaState=1;
hiX(ledIntRda);
rdaDataCounter=0;
rdaTempCounter=0;
while(rdaTempCounter<10000)
{
rdatempCounter++;
if (kbhit(gsm))
{
chr=fgetc(gsm);
if(chr>32)
{
rdaData[rdaDataCounter]=chr;
rdaDataCounter++;
rdaTempCounter=0;
}
}
}
rdaData[rdaDataCounter]=0;
lox(ledIntRda);
}
#INT_RDA2
void RDA2_isr(void)
{
intRda2State=1;
}
void main()
{
//setup_adc_ports(sAN0|sAN1|sAN2|sAN3|sAN4);
//setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
digOut(gsmPowerEnable);
digOut(iAmAlive);
digIn(intExt0);
digIn(intExt1);
digIn(gsmPowerOut);
ext_int_edge(H_TO_L);
bekle(2*tSn);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
/*
enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
*/
enable_interrupts(GLOBAL);
hiX(iAmAlive);
gsmModulePower(enable);
processPlanner=0;
ringCount=0;
ringTempCounter=0;
while(TRUE)
{
//interruptlar
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_RDA);
//Görev zamanlayıcısı her artırımda 1ms bekle
//istediğin sayıya / zamana gelince çalıştır.
processPlanner++;
bekle(tMicro);
if(processPlanner%1000==0)
{
fprintf(dbg,"FiDeNet R:%u RTC:%lu diff:%lu \r\n"ringCount,ringTempCounter,diff);
//fprintf(gsm,"ATH\r\n" );
}
if(intRdaState==1)
{
intRdaState=0; //resetle
fprintf(dbg," rdaData:-%s-\r\n"rdaData);
//RING text sayılıyor
strcpy(tempBuffer,gsmResp[RING].str);
resp=strcmp(tempBuffer,rdaData);
fprintf(dbg,"strcmp resp:%u\r\n"resp);// RING textini yakala
if (resp==0)
{
ringCount++;
ringTempCounter=processPlanner;
}
if (ringCount>=ringCountMax)
{
fprintf(dbg,"Gsm Module Answers Call\r\n");
fprintf(gsm,"%s"sendCmdDefaults[eATA].cmdText);
ringCount=0;
}
}
if(intRda2State==1)
{
intRda2State=0; //resetle
}
if (intExtState==1)
{
intExtState=0;
fprintf(dbg,"Ext0\r\n");
fprintf(gsm,"%s"sendCmdDefaults[eATH].cmdText);
bekle(2*tSn);
fprintf(dbg,"Halt and Redial\r\n");
fprintf(gsm,"%s"sendCmdDefaults[eATD1].cmdText);
}
if (intExt1State==1)
{
intExt1State=0;
fprintf(dbg,"Ext1\r\n");
fprintf(gsm,"%s"sendCmdDefaults[eATH].cmdText);
bekle(2*tSn);
fprintf(dbg,"Halt and Redial\r\n");
fprintf(gsm,"%s"sendCmdDefaults[eATD2].cmdText);
}
intExtFirst=0;
//Gereksiz durumlarda yada çalıp kapanan telefonlarda ringCount değişkenini sıfırla
if (processPlanner>ringTempCounter)
{
diff=processPlanner-ringTempCounter;
}
else
{
diff=ringTempCounter-processPlanner;
}
//diff=abs(processPlanner-ringTempCounter);
if ((ringCount>0) && (diff>25000))
{
ringCount=0;
fprintf(dbg," ringCount sıfırlandı\r\n");
}
}
}
/*Cihaz ile ilgili kullanılacak sabitler*/
enum sabitler{
cHWID,
cSWVersion,
cHwR,
mfc, //manifacturer
};
typedef struct hw_strings{
u8 sbt;
char str[20];
}myHwStrings;
myHwStrings const deviceData[10]={
cHWID,{"FD.EECP.R01"},
cSWVersion,{"1.0.0"},
cHwR,{"1.0.1"},
mfc,{"FiDeNet UKoSis"},
};
enum enumCommands{
cAT,
cATHwID,
cATSw,
cATHwR,
cATMfc, //manifacturer
cATID,
cATIDW,
cATIDC,
};
typedef struct strctCommandText{
u8 sbt;
char str[20];
}myHwCommands;
myHwCommands const MyCommands[15]={
cAT,{"AT\r"},
cATHwID,{"ATHwID\r"},
cATSw,{"ATSw\r"},
cATHwR,{"ATHwR\r"},
cATMfc,{"ATMfc\r"},
cATID,{"ATID\r"},
cATIDW,{"ATIDW="},
cATIDC,{"ATIDC\r"},
};
u16 counterGen; //genel sayaç
u8 resp;
u16 processPlanner;
u8 readDevIDOk=0;
u8 devIDAddr=10;
char devID[30];
//rda rutini değişkenleri
char tempBuffer[30]; // id yazma için kullanılan ara değişken
char chr;
//char rdaBuffer[100];
//char rda2Buffer[100];
u16 rdaTempcounter;
u16 rda2Tempcounter;
u8 rdaDataCounter;
u8 rda2DataCounter;
u1 intRdaState=0;
u1 intRda2State=0;
u1 intExtState=0;
u1 intExt1State=0;
char rdaData[100];
char rda2Data[100];
char strGen1[10];
u16 genCounter;
u8 genCounter2;
//GSM commands and regs
u1 gsmPowerState;
u1 intExtFirst=1;
u8 ringCount;
u16 ringTempCounter;
u8 ringCountMax=2;
u16 diff;
//gsm response durumları tanımla // ilerde artacak
enum state{
OK,
CONNECT,
RING,
NO_CARRIER,
ERROR,
CREG,
COPS,
SMS_text, //girilen yeni durumları buradan sonra gir EMPTY en sonda olsun
EMPTY,
CALLREADY
};
#define maxMyGsmResponseChar 20 //dönen modem cevabı için max char size
#define responseNr 20
//dönen cevap sayısı
typedef struct myGsmResponse{
u8 cmd;
char str[maxMyGsmResponseChar];
}myGsmResp;
myGsmResp const gsmResp[responseNr]={
OK,{"OK"},
CONNECT,{"CONNECT"},
RING,{"RING"},
NO_CARRIER,{"NO_CARRIER"},
ERROR,{"ERROR"},
CREG,{"+CREG: 0,1"},
COPS,{"+COPS: 0,0"},
SMS_text,26,
EMPTY,0
};
//Komutlar için struct
enum{
eAT, //0
eATA,
eATE0,
eATV0,
eATQ0,
eATCREG,
eATCOPS,
eATCTZU,
eATQNITZ,
eATCCLK,
eATH,
eATD1,
eATD2
};
#define RESPONSE_MAX_CHAR 55
#define CMD_NUMBER 40 // yukarıda 40 tane modem komutu var
typedef struct myCommandType{
u8 Cmd; // enum içindeki komutları tutar (gönderdiğin veya cevap alacağın komutun ne olduğunu buradan anlarsın)
vu16 Timeout; // her komutun timeout'u için kullanılır
vu8 cmdText[RESPONSE_MAX_CHAR]; // modemden gelen veya gidecek data, interrupt içinde usarttan bu buffer'a kopyalancağından volatile yaptım
vu8 text[RESPONSE_MAX_CHAR];
// herşeyi buraya ekleyebilirsin
}MyModemStructTypedef;
MyModemStructTypedef const SendCmdDefaults[CMD_NUMBER]={
eAT, 100,{"AT\r\n"},{"AT"},
eATA,100,{"ATA\r\n"},{"AT"},
eATE0, 30,{"ATE0\r\n"},{"ATE0"},
eATV0, 30,{"ATV0\r\n"},{"ATV0"},
eATQ0, 30,{"ATQ0\r\n"},{"ATQ0"},
eATCREG,30,{"AT+CREG?\r\n"},{"AT+CREG?"},
eATCOPS,1000,{"AT+COPS?\r\n"},{"AT+COPS?"},
eATCTZU,300,{"AT+CTZU=3\r\n"},{"AT+CTZU=3"},
eATQNITZ,300,{"AT+QNITZ=1\r\n"},{"AT+QNITZ=1"},
eATCCLK,300,{"AT+CCLK?\r\n"},{"AT+CCLK?"},
eATH,300,{"ATH\r\n"},{"ATH"},
eATD1,1000,{"ATD>1;\r\n"},{"ATD>1;"},
eATD2,1000,{"ATD>2;\r\n"},{"ATD>2;"},
};
typedef int1 u1;
typedef unsigned int8 u8;
typedef volatile unsigned int8 vu8;
typedef unsigned int16 u16;
typedef volatile unsigned int16 vu16;
typedef unsigned int32 u32;
#define bekle(x) delay_ms(x)
#define digOut(x) output_drive(x)
#define digIn(x) output_float(x)
#define gsmPowerEnable Pin_C1
#define gsmOnOff Pin_B2
#define hiX(x) output_high(x)
#define loX(x) output_low(x)
#define disable 0
#define enable 1
#define debug
#define iAmAlive Pin_C3
#define ledIntRda Pin_C2
#define ledIntRda2 Pin_C4
#define ledIntExt Pin_C5
#define intExt0 Pin_B0
#define intExt1 Pin_B1
#define gsmPowerOut Pin_B5
#define gsmOnOffTrig Pin_B2
//#define lcdBacklight Pin_B14
#define tSn 1000
#define tUzun 500
#define tOrta 100
#define tKisa 50
#define tMini 10
#define tMicro 1
void gsmModulePower(u1 state)
{
if(state==1) //GSM modul açılması isteniyorsa
{
hiX(gsmPowerEnable);
bekle(tSn);
gsmPowerState=input(gsmPowerOut);
if (gsmPowerState==0) //GSM module kapalı ise
{
hiX(gsmOnOffTrig);
bekle(tSn);
loX(gsmOnOffTrig);
fprintf(dbg,"GSM On Off Trigged\r\n");
}
else
{
fprintf(dbg,"GSM is already on\r\n");
}
}
else //state==0 GSM modul kapanması isteniyorsa
{
hiX(gsmOnOffTrig);
bekle(tSn);
loX(gsmOnOffTrig);
fprintf(dbg,"GSM is shut off\r\n");
}
}
Comments