처음으로 실습관련 이야기를 작성하게 되는 거 같습니다.
현재 전 직장 동료인 친구와 side project 하나를 준비중에 있습니다.
그런데 제가 아두이노를 손을 안댄지도 오래되었고 살짝 야매로 배워서 개념을 다시 잡고
side project에 필수 원리가 될 code를 연습용으로 만들어 보았고, 이를 소개해보고자 합니다.
Android studio에서 Arduino NANO 33 IOT 제어하기
1. arduino 회로 설계
우선 가볍게 led만 제어 할 생각이므로 가볍게 설계하면 됩니다.
이런 식으로 led만 연결해줍니다.
2. arduino code
3. android studio code
1) build gradle(module)
viewBinding {
enabled = true
}
우선 저는 binding을 좋아하니깐 추가해줍시다.
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
저는 전에도 많은 글을 썼지만 retrofit2를 이용한 rest 구현을 좋아하므로 추가해줍니다.
2) manifast.xml
<uses-permission android:name="android.permission.INTERNET" />
internet을 이용한 통신을 해야하므로 permission을 추가해줍니다.
만약 최종적으로 debuging할 때 오류가 생긴다면
android:usesCleartextTraffic="true"
해당 코드를 추가해줍시다.
3) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="LED 제어하기"
android:textSize="30dp"
android:textColor="@color/black"
android:layout_margin="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/led_on"
android:layout_margin="5dp"
android:text="on" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/led_off"
android:layout_margin="5dp"
android:text="off" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
어차피 test용이기 때문에 최대한 간단하고 빠르게 작성해줍니다.
4) data model
package com.example.basil
import com.google.gson.annotations.SerializedName
data class BasilModel(
@SerializedName("ledOnOff")
val ledControll: String,
)
어차피 arduino에 전달해 줘야 할 값은 text 1개이므로 string 변수 1개를 만들어 줍니다.
* data는 1개만 있으므로 @serializedName은 생략을 추천드립니다.
5) api 설계
package com.example.basil
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
interface BasilAPI {
@POST("post")
suspend fun controllLed(@Body basilModel: BasilModel):Response<Void>
}
retrofit2를 이용하여 기존에 정의한 string 변수를 arduino로 post합니다.
6) object 설계
package com.example.basil
import com.example.basil.BasilObject.BASE_URL
import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object BasilObject {
private const val BASE_URL = "arduino nano 33 iot의 ip주소"
private val getRetrofitBasil by lazy {
Retrofit.Builder()
.baseUrl(BasilObject.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.build()
}
val getRetrofitBasilService : BasilAPI by lazy { getRetrofitBasil.create(BasilAPI::class.java) }
fun getInstance(): BasilAPI? {
return getRetrofitBasilService
}
}
사실 object 설계의 의의는 객체지향을 추구하고자 중복된 코딩을 최소화 하기 위해서입니다.
7) MainActivity.kt
package com.example.basil
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.example.basil.databinding.ActivityMainBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import retrofit2.Response
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.ledOn.setOnClickListener {
val text = "/ledOn"
sendText(text)
}
binding.ledOff.setOnClickListener {
val text = "/ledOff"
sendText(text)
}
}
private fun sendText(text: String) {
val model = BasilModel(text)
GlobalScope.launch(Dispatchers.IO) {
val response = BasilObject.getRetrofitBasilService.controllLed(BasilModel(text.toString()))
if (response.isSuccessful){
Log.d("success","data sent successfully")
} else {
Log.e("error","failed to send data")
}
}
}
}
arduino code에서 client가 text로 ledon or ledoff를 보내면 조건이 성립되게 정의 했으므로
button 선택에 따라 text값을 다르게 보내면 성공입니다.
4. 최종 완성본
해당 영상을 보시면 android studio에서 on/off button을 누르면 arduino의 led가 상황에 맞춰 on/off됩니다.
5. 이 글을 마무리하며
앞으로 해당 code는 side project를 진행하며 조금씩 수정하며 사용할 생각입니다.
또한 side project를 진행하며 생기는 과정에서 유익한 부분은 계속해서 블로그에 올릴 생각입니다.
이번에 실습 내용을 처음으로 작성해보았는데 분량이 정말 길게 되더라고요
긴 글 읽어 주셔서 감사합니다.
'Arduino' 카테고리의 다른 글
비전공자를 위한 Arduino를 이용하여 android 폰으로 Iot 전등 제어하기2(Arduino편) (1) | 2023.09.18 |
---|---|
비전공자를 위한 Arduino를 이용하여 android 폰으로 Iot 전등 제어하기(android편) (0) | 2023.09.09 |
오류범벅(ESP8266, ESP-01, Arduino UNO) (0) | 2023.05.25 |
안드로이드로 아두이와 서버통신 제어하기(WIFI D1 R1, ESP8266, 모터제어, JSON) (0) | 2023.05.09 |
두근두근 납땜하기 (0) | 2023.04.29 |